希望能够到一个城市分配给用户,只要用户 被分配到相关城市
您可以在全国你也不应该。
创建一个国家。创建一个城市并将其分配给一个国家。创建一次旅行或访问,分配该访问或城市旅行,然后将用户添加到该旅程或访问。瞧!你有你需要的关系!我认为。
一个城市belongs_to的国家 之旅belongs_to的城市 belongs_to的城市 的访问用户的has_many访问 用户的has_many车次 因为无论旅行和参观属于一个城市,你可以通过双方关系具有的has_many因此访问和旅行表需要城市和用户ID 而且您拥有所需的关系和所需的逻辑。
不要试图做一些违反您的要求的事情,如直接将用户加入城市,因为城市无法分配给用户。事实上,只是为了给你一个更大的头痛,你甚至可能想要在许多国家的许多城市进行许多次旅行。在这种情况下,您希望访问被分配到不是城市的旅行。
这是一个逻辑问题,而不是编码问题。
UPDATE在回应评论
class User < ApplicationRecord
has_many :trips
has_many :cities, through: :trips
end
class Trip < ApplicationRecord
belongs_to :user
belongs_to :city
end
class City < ApplicationRecord
has_many :trips
has_many :users, through: :trips
end
然后在控制台
Loading development environment (Rails 5.1.4)
2.4.0 :001 > u = User.create(name: "Fred")
(0.0ms) begin transaction
SQL (0.3ms) INSERT INTO "users" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "Fred"], ["created_at", "2017-09-17 14:24:30.720005"], ["updated_at", "2017-09-17 14:24:30.720005"]]
(16.3ms) commit transaction
=> #<User id: 1, name: "Fred", created_at: "2017-09-17 14:24:30", updated_at: "2017-09-17 14:24:30">
2.4.0 :004 > c = City.create(name: "Leeds")
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "cities" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "Leeds"], ["created_at", "2017-09-17 14:26:19.293166"], ["updated_at", "2017-09-17 14:26:19.293166"]]
(33.9ms) commit transaction
=> #<City id: 1, name: "Leeds", created_at: "2017-09-17 14:26:19", updated_at: "2017-09-17 14:26:19">
2.4.0 :005 > t = Trip.create(name: "T1", user: u, city: c)
(0.2ms) begin transaction
SQL (0.5ms) INSERT INTO "trips" ("user_id", "city_id", "name", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["user_id", 1], ["city_id", 1], ["name", "T1"], ["created_at", "2017-09-17 14:28:44.656390"], ["updated_at", "2017-09-17 14:28:44.656390"]]
(26.0ms) commit transaction
=> #<Trip id: 1, user_id: 1, city_id: 1, name: "T1", created_at: "2017-09-17 14:28:44", updated_at: "2017-09-17 14:28:44">
2.4.0 :006 > t.user.name#
=> "Fred"
2.4.0 :007 > t.city.name
=> "Leeds"
2.4.0 :008 > t.name
=> "T1"
所以这是一个正常的has_many通过的作品,但你想怎么上了趟模型的has_many城市,所以我会更新如何这将很快奏效
好的,为了实现下一个旅程有很多城市和一个城市has_many旅行的阶段,请注意has_many在关系的两边你是需要一个新的交叉引用表,可能叫做trip_city_xref,它具有city_id和trip_id的复合主键
这是Rails术语,它是一个我讨厌的has_and_belongs_to_many关系。我认为只有has_and_belongs_to_many是Rails唯一错误的东西。这是一个捷径。其他人会不同意,但这是我如何用一种没有捷径的语言来设置它的。我认为这是更清晰和不太模糊的。所以,我会成立这样的
class Trip < ApplicationRecord
belongs_to :user
belongs_to: :city_trip_xref and
has_many :cities, through: :city_trip_xref
end
class City < ApplicationRecord
has_many :trips, through: :city_trip_xref
has_many :users, through: :trips
end
class CityTripXref < ApplicationRecord
belongs_to :trip
belongs_to :city
end
这是我个人的意见可以随意去has_and_belongs_to_many读了here 那么你与你的用户现在怎么办?同样,稍后我会更新
UPDATE User.cities 所以你的用户模型可能看起来像这样
class User < ApplicationRecord
has_many :trips
has_many :city_trip_xrefs, through: :trips
def cities
trips.map(&:city_trip_xrefs).flatten.map(&:city)
end
end
要获得所有用户的一趟逛城市,你可以扁平化和映射关系像这样 U = User.first u.trips.map(&:city_trip_xrefs).flatten.map(&:市)
所以,你可以让你的用户类的方法来获得使用上述应保尽保显示在上面的用户模型中。至于为用户分配一个城市,好吧,你不会直接这样做。您将设置一次旅行,将用户和城市添加到该行程,然后在真实世界的示例中可能需要所有功能,除非您的要求有所不同
使用上述创建的记录在控制台加上在city_trip_xref表中的记录加入到多对多前往城市的一个现有的城市和绊倒你现在可以做
首先在控制台中创建外部参照
ctx = CityTripXref.new
=> #<CityTripXref id: nil, city_id: nil, trip_id: nil, created_at: nil, updated_at: nil>
2.4.0 :008 > ctx.city = City.first
=> #<City id: 1, name: "Leeds", created_at: "2017-09-17 14:26:19", updated_at: "2017-09-17 14:26:19">
2.4.0 :009 > ctx.trip = Trip.first
=> #<Trip id: 1, user_id: 1, city_id: 1, name: "T1", created_at: "2017-09-17 14:28:44", updated_at: "2017-09-17 14:28:44">
2.4.0 :010 > ctx.save
下一个GET第一位用户首次出行的第一个城市的名称
2.4.0 :028 > u = User.first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Fred", created_at: "2017-09-17 14:24:30", updated_at: "2017-09-17 14:24:30">
2.4.0 :029 > u.cities.first.name
Trip Load (0.1ms) SELECT "trips".* FROM "trips" WHERE "trips"."user_id" = ? [["user_id", 1]]
CityTripXref Load (0.1ms) SELECT "city_trip_xrefs".* FROM "city_trip_xrefs" WHERE "city_trip_xrefs"."trip_id" = ? [["trip_id", 1]]
City Load (0.1ms) SELECT "cities".* FROM "cities" WHERE "cities"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> "Leeds"
2.4.0 :030 >
希望是有道理的。
您可以只创建两个标准连接表:'countries_users'和'cities_users',并且在后者上写**模型验证**来声明城市已分配给用户? –
备注:您大概也需要某种预先或删除后的逻辑,以防止用户被**从一个国家分配**,但仍然分配给城市。 (即,不允许这样的删除,或者删除其他关联作为交易的一部分。) –
您无法以用户has_many城市的身份将城市分配给用户?用户需要属于城市以便能够为用户分配城市!您真正想要的是将访问分配给用户并指定一个城市进行访问。将你的问题更新到一个有意义的问题,也许我可以进一步提供帮助。废弃简化它导致你的问题,并让你认为你应该能够做的事情,打破你的要求 – jamesc