有很多关于如何设置has_many :through
的教程,但还没有足够的关于如何实际操作的教程!
我有一个由Inventories
加入的Requests
和Bookings
表格。例如:可能有3个贷款人在库存中有帐篷,每个贷款人都有3个其他借款人要求。我想要做的是对于库存中的3个帐篷中的每个帐篷,向贷款人显示请求帐篷的3个借款人的列表。然后贷款人可以选择他/她想成为最终借款人的人。
我想知道这应该如何运作,但不知道它是否正确,所以请提供以下建议!该操作由Requests
控制器驱动。让我们来看一个示例,其中Inventories
表已经有3个帐篷,[1, 2, 3]
。让我们说Borrower Pat为帐篷提交Request_ID 1
。
我是否应该创建3个新的Bookings
所有Request_ID 1
然后Inventory_ID [1, 2, 3]
以获得所有可想到的组合?像
Inventory.where(name: "tent").each { |inventory| @request.bookings.create(inventory_id: inventory.id) }
然后在Bookings
和Request
中使用Inventory
主键作为外键是否正确?这意味着在借款人Pat提交请求后,bookings_id
将一直为空,直到贷方2接受为止,此时bookings_id
等于与Request_ID 1
和{{1}的组合相匹配的ID }}
现在让我们说当发布Inventory_ID 2
并发出Request
时,我会向贷方发送电子邮件。然而,我意识到如果3个借款人在同一时期想要她的帐篷,我不想打扰贷款人泰勒。我会在第一时间给她发电子邮件,然后是她在登录时说出是或否的随后的电子邮件。在这种情况下,可以在创建操作中查询Bookings
表,例如(在上面展开)
-
Bookings
上面的代码可能有缺陷,我只是想知道这应该如何工作的理论。
答案 0 :(得分:1)
加入表格
首先,has_many :through
使用连接表 - 一个用于为其他表标识两个不同foreign_keys
的中央表。这就是提供through
功能的原因:
有些琐事:
has_and_belongs_to_many
表名为[plural_model_1]_[plural_model_2]
,模型需要按字母顺序排列(entries_users
)
has_many :through
联接表可以被称为任何内容,但通常称为[alphabetical_model_1_singular]_[alphabetical_model_2_plural]
-
<强>模型强>
has_many :through
模型通常按如下方式构建:
#app/models/inventory.rb
Class Inventory < ActiveRecord::Base
has_many :bookings
has_many :requests, through: :bookings
end
#app/models/booking.rb
Class Booking < ActiveRecord::Base
belongs_to :inventory
belongs_to :request
end
#app/models/request.rb
Class Request < ActiveRecord::Base
has_many :bookings
has_many :requests, through: :bookings
end
-
<强>代码强>
你的代码非常臃肿 - 你做这样的事情要好得多:
#app/controllers/inventories_controller.rb
Class InventoriesController < ApplicationController
def action
@tents = Inventory.where name: "tent"
@tents.each do |tent|
booking = Booking.find_or_create_by inventory_id: tend.id
AlertMail.mail_to_lender(tent).deliver if booking.is_past_due?
end
end
end
#app/models/booking.rb
Class Booking < ActiveRecord::Base
def is_past_due?
...logic here for instance method
end
end
你应该只引用一次 - 它被称为DRY(不要自己重复)
答案 1 :(得分:1)
我在问这个问题时表现不佳。我想知道的是如何在DB和模型文件中设置所有内容后创建实际的关联。
如果要创建与现有A记录处于多对多关系中的B记录,则它与A.Bs.create
的语法相同。对我来说更重要的是如何链接已经存在的A和B,在这种情况下答案是A.B_ids += B_id
。
另外两件事:
更明显:如果你以某种方式创建/链接某些东西,那么另一种方式是自动的吗?是的,当然。在多对多关系中,如果您已完成A.B_ids += B_id
,则不再需要执行B.A_ids + = A_id`。
不太明显:如果A和B由表AB连接,表AB的主键不需要添加到A或B.Rails要求你担心AB表少尽可能地,搜索,构建等都可以通过A.B
或B.A
代替A.AB.B
或B.AB.A