更新了问题,因为原版过于简单化,感谢Aaron McLeod又名AGMCLEOD,以帮助您突出显示
我的问题是,我不能让它工作,而是让它按我想要的方式工作。
问题
想象一下3个模型,公司,分支机构和联系人,它们通过CompanyContacts模型或查找表链接在一起。
表company_contacts看起来像这样:
+------------+-----------+------------+
| company_id | branch_id | contact_id |
+------------+-----------+------------+
我将联系人与分支机构和公司联系起来的理想陈述应该是:
update company_contacts set contact_id = x where branch_id = y AND company_id = z
所以问题是,如何使用ActiveRecord实现这一目标?您是否创建了自定义方法来一次性设置它?
我的模特中有什么
公司联系模式
belongs_to :company, :class_name => "Company", :foreign_key => :company_id
belongs_to :branch, :class_name => "Branch", :foreign_key => :branch_id
belongs_to :contact, :class_name => "Contact", :foreign_key => :contact_id
公司模式
has_many :company_contacts
has_many :branches, :through => :company_contacts, :source => :branches
has_many :contacts, :through => :company_contacts, :source => :contacts
分支模型
has_many :company_contacts
has_many :companies, :through => :company_contacts, :source => :companies
has_many :contacts, :through => :company_contacts, :source => :contacts
我希望能够做到以下但是不可能
has_one :company, :through => :company_contacts, :source => :company
当然我可以通过
来模拟它def branch
Branch.companies.first
end
联系模式
has_many :company_contacts
has_many :branches, :through => :company_contacts, :source => :branches
has_many :companies, :through => :company_contacts, :source => :companies
理想情况下,我想拥有,has_one分支和has_one公司
创建联系人时的当前解决方案<<到分支导致创建两行
+------------+-----------+------------+
| company_id | branch_id | contact_id |
+------------+-----------+------------+
| 1 | 1 | nil |
+------------+-----------+------------+
| nil | 1 | 1 |
+------------+-----------+------------+
什么时候,实际上我想要实现的是:
+------------+-----------+------------+
| company_id | branch_id | contact_id |
+------------+-----------+------------+
| 1 | 1 | 1 |
+------------+-----------+------------+
我能想到的唯一方法是创建一个自定义方法
我将继续尝试解决我的问题并发布我的发现 期待您的回复
提前致谢。
答案 0 :(得分:1)
好的,在发布问题之后,我发现了很多更多的东西,我遇到了类似的这个令人敬畏的答案。 zetetic提供了一个非常详细的答案,我更深入地阅读了如何解决这个问题。
首先是灵感:has_many :through multiple has_one relationships?
现在回答:
在ContactController的create方法中,神奇的1行代码是:
@contact.company_contacts.build(:company_id => @company.id, :branch_id => @branch.id)
完全在ContactController的create方法中:
# fetch the branch and company ids first
@contact = Contact.new(params[:contact])
@contact.company_contacts.build(:company_id => @company.id, :branch_id => @branch.id)
@contact.save
它完全符合我的目标:
INSERT INTO "company_contacts" ("branch_id", "company_id", "contact_id") VALUES (?, ?, ?) [["branch_id", 2], ["company_id", 4], ["contact_id", 12]]
Phew - 出于某种原因带我一段时间,看起来很简单!
答案 1 :(得分:0)
要解决此问题,您可以执行以下操作。假设您通过表单传递了分支ID和公司ID,或者您已经在网址中传递了它。
def create
@contact = Contact.new(params[:contact])
if @contact.save
cc = CompanyContact.new(:contact_id => @contact.id, :branch_id => params[:branch_id], :company_id => params[:company_id])
cc.save
redirect_to contacts_url, :notice => "Contact saved"
else
render :action => "new"
end
end
您可能需要调整参数名称等,但这应该有效。因为它有点三通连接,所以我不确定是否可以在联系对象上构建它。