【问题标题】:has_one and belongs_to togetherhas_one 和 belongs_to 在一起
【发布时间】:2013-10-24 20:51:14
【问题描述】:

乍一看,这似乎是一个简单的问题。你甚至可能怀疑它之前已经回答过了,但不是相当。我已经在网上进行了大量搜索(包括堆栈溢出),但一直找不到答案。

这是我能找到的最接近的东西:Using has_one and belongs_to together 但它并不能完全回答我的问题。

我正在使用 Rails 4 和 MySQL

数据库结构如下:

合作伙伴表

id
name
primary_contact_id

联系人表

id
partner_id
first_name
last_name

很简单,对吧?不言自明。

class Partner < ActiveRecord::Base

    has_one :primary_contact, :class_name => "Partners::Contact", :primary_key => 'primary_contact_id'

    has_many :contacts, :class_name => "Partners::Contact"

    accepts_nested_attributes_for :primary_contact

    validates_presence_of :primary_contact

end

class Partners::Contact < ActiveRecord::Base

    belongs_to :partner

end

如您所见,在创建合作伙伴时,需要一个主要联系人(表格等都已正确设置)

我遇到的唯一问题是,当 primary_contact 与合作伙伴一起创建时,ActiveRecord 不明白它需要将正在创建的联系人上的 partner_id 分配给正在创建的 partner_id。 ..

这里的最佳做法?我不想在联系人表中创建一个列来指示(布尔或其他)该联系人是否是主要联系人。这不是正确的数据库规范化(不管“rails 约定”吹捧什么)。

感谢您的帮助和想法!

【问题讨论】:

    标签: ruby-on-rails activerecord rails-activerecord database-normalization


    【解决方案1】:

    我假设您正在以类似于以下方式创建合作伙伴:

    Partner.create params[:partner] # { ..., primary_contact: {} }
    

    因此,rails 无法知道您正在这里建立联系。一种不调整架构的简单解决方案是使用额外的查询来规范化数据:

    class Partner
      after_create :update_primary_contact
    
      def update_primary_contact
        self.contacts << self.primary_contact
      end
    end
    

    【讨论】:

    • 这听起来是个好主意。我刚刚尝试过,但是由于创建合作伙伴的方式 params.require(:partner).permit(:company_name, ... primary_contact_attributes: ...) 我的测试仍然失败...
    猜你喜欢
    • 2014-05-05
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    相关资源
    最近更新 更多