has_many:通过Rails 3.1.1

时间:2012-01-11 00:22:27

标签: ruby-on-rails ruby activerecord ruby-on-rails-3.1

更新了问题,因为原版过于简单化,感谢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          |
+------------+-----------+------------+

我能想到的唯一方法是创建一个自定义方法

我将继续尝试解决我的问题并发布我的发现 期待您的回复

提前致谢。

2 个答案:

答案 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

您可能需要调整参数名称等,但这应该有效。因为它有点三通连接,所以我不确定是否可以在联系对象上构建它。