Rails has_many:通过:primary_key

时间:2013-07-16 01:40:59

标签: ruby-on-rails ruby activerecord

我正在尝试通过rails has_many创建多对多关系:但是我需要使用不同的列创建关系,而不是使用模型主键(id)。 这是我的模型(顺便说一句,我使用的是Rails 4):

class Food < ActiveRecord::Base
  validates :NDB_No, uniqueness: true
  validates :NDB_No, :FdGrp_Cd, :Long_Desc, :Shrt_Desc, presence: true

  has_many :langual_factor_associations, primary_key: 'NDB_No', foreign_key: 'NDB_No'
  has_many :langual_factor_descriptions, through: :langual_factor_associations, primary_key: 'NDB_No', foreign_key: 'NDB_No'
end

class LangualFactorAssociation < ActiveRecord::Base
  validates :NDB_No, :Factor_Code, presence: true

  belongs_to :food, foreign_key: 'NDB_No'
  belongs_to :langual_factor_description, foreign_key: 'Factor_Code'
end

class LangualFactorDescription < ActiveRecord::Base
  validates :Factor_Code, uniqueness: true
  validates :Factor_Code, :Description, presence: true

  has_many :langual_factor_associations, primary_key: 'Factor_Code', foreign_key: 'Factor_Code'
  has_many :foods, through: :langual_factor_associations, primary_key: 'Factor_Code', foreign_key: 'Factor_Code'

end

与LangualFactorAssociation的has_many关联适用于Food和LangualFactorDescription。但是has_many通过:Food和LangualFactorDescription之间的关联不起作用。这是我尝试访问Food.LangualFactorDescriptions时出现的错误:

Food::should create the proper relations to the LangualFactorDescription
            model#test_0002_must create the proper associations:
ActiveRecord::StatementInvalid: PG::Error: ERROR:  operator does not exist: integer = character varying
LINE 1: ...sociations" ON "langual_factor_descriptions"."id" = "langual...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT  "langual_factor_descriptions".* FROM "langual_factor_descriptions" INNER JOIN "langual_factor_associations" ON "langual_factor_descriptions"."id" = "langual_factor_associations"."Factor_Code" WHERE "langual_factor_associations"."NDB_No" = $1  ORDER BY "langual_factor_descriptions"."id" ASC LIMIT 1
    test/models/food_test.rb:172:in `block (3 levels) in <top (required)>'

我认为问题是查询的这一部分 ON“langual_factor_descriptions”。“id”=“langual_factor_associations”。“Factor_Code”。我认为设置primary_key和/或foreign_key选项会解决这个问题,但事实并非如此。事实上,如果我从模型中删除它们并将其保留为

has_many :langual_factor_descriptions, through: :langual_factor_associations

rails生成完全相同的查询,因此在我看来,设置这些选项什么都不做。我在这里错过了什么吗?关于如何告诉rails不要寻找langual_factor_descriptions.id而是langual_factor_descriptions.Factor_Code的任何想法?

以下是我阅读过的有关此主题的一些最相关的资源: http://guides.rubyonrails.org/association_basics.html

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

has_many :through with :primary_key on join table not working(这几乎是我遇到的问题,但我不确定这是否是正确的解决方案)

Rails has_many association with multiple keys

https://www.ruby-forum.com/topic/139765

Has Many Through Alternative Primary and Foreign Keys

1 个答案:

答案 0 :(得分:3)

我想我解决了这个问题。这是代码:

class Food < ActiveRecord::Base
  validates :NDB_No, uniqueness: true
  validates :NDB_No, :FdGrp_Cd, :Long_Desc, :Shrt_Desc, presence: true

  has_many :langual_factor_associations, primary_key: 'NDB_No', foreign_key: 'NDB_No'
  has_many :langual_factors, through: :langual_factor_associations    
end

class LangualFactorAssociation < ActiveRecord::Base
  validates :NDB_No, :Factor_Code, presence: true

  belongs_to :food, primary_key: 'NDB_No', foreign_key: 'NDB_No'
  belongs_to :langual_factor, primary_key: 'Factor_Code', foreign_key: 'Factor_Code'
end

class LangualFactor < ActiveRecord::Base
  validates :Factor_Code, uniqueness: true
  validates :Factor_Code, :Description, presence: true

  has_many :langual_factor_associations, primary_key: 'Factor_Code', foreign_key: 'Factor_Code'
  has_many :foods, through: :langual_factor_associations    
end

请注意,我没有在has_many through:associations中使用foreign_key和primary_key选项,并且不需要self.primary_key

此外,还有一些其他有用的链接帮助了我:

http://railsforum.com/viewtopic.php?id=36186

http://guides.rubyonrails.org/v2.3.11/active_record_querying.html

尽管问题的解决方案巧合,但我相信这些链接提供了相关信息。