假设我有一个虚构的汽车租赁应用程序。
我有用户,汽车和地址。
user (id, name, email)
has_many :addresses
has_many :cars
car (id, name)
belongs_to :user
address (id, name, user_id)
belongs_to :user
每个用户都有多个地址和汽车。地址是用户可以借出汽车的地方。
现在,有了这个模型,我想做以下事情(假设用户#1有2个地址和3辆车):
Settings for User #1 :
(specify at which address each of your cars are available)
/-------------------------------------------\
| | Car #1 | Car #2 | Car #3 |
|-----------+----------+---------+----------|
| Address 1 | yes | yes | no |
|-----------+----------+---------+----------|
| Address 2 | no | no | yes |
\-------------------------------------------/
我认为要实现这一点,你可以创建一个表cars_addresses
(id,car_id,address_id,available:bool)
但我不知道如何用活动记录来指定。所以我的问题是:
答案 0 :(得分:2)
您需要的是汽车和地址之间的has_and_belongs_to_many。然而,大量的rubbyists会说这种关系永远不应该被使用(并且has_many:通过应该使用)这是一个完美的地方,因为我无法想到需要存储在这些模型之间的任何其他信息。所以它会是:
user (id, name, email)
has_many :addresses
has_many :cars
car (id, name)
belongs_to :user
has_and_belongs_to_many :addresses
address (id, name, user_id)
belongs_to :user
has_and_belongs_to_many :cars
然后你需要创建表addresses_cars(订单很重要,没有模型需要),没有id和两个collumns:address_id和car_id。而已!它会“神奇地”起作用:
user.cars.first.addresses => list of location car is available
user.addresses.first.cars => list of cars available under address
user.addresses.first.cars << user.cars.first => add a car to given address
答案 1 :(得分:1)
这取决于你的'汽车'模型代表什么。
如果它是一辆不能同时位于多个地点的实体车,那么另一种关系就是:
car (id, name, location_id)
belongs_to :user
belongs_to :location
location (id, name, user_id)
belongs_to :user
has_many :cars
这将使关系发挥作用:
#list each car and it's location
current_user.cars.each do |car| { puts "#{car.name} is at #{car.location.name}" }
或
#how many cars are at each location
current_user.locations.each do |location| { puts "#{location.cars.count} of your cars are at #{location.name}" }
设置汽车的位置:
#move car with id=5 to location with id=15
c=Car.find(5)
l=Location.find(15)
c.location=l
c.save
或
c=Car.find(5)
c.location_id=15
c.save
顺便说一句,我建议将您的模型命名为“位置”而不是“地址”。 Ruby自动生成许多具有模型多个名称的方法,因此使用简单复数形式的单词将帮助您避免一些混淆。