Rails has_one:通过自我指导协会1对1对1

时间:2010-12-07 16:47:42

标签: ruby-on-rails database database-design associations

我有一个Factsheet模型,其中包含各种出版物,包括备用语言版本。不同的语言版本应该作为单独的记录分开(因为它们可以单独订购/更新/等),但我试图将它们相互关联,以便您可以轻松地判断一个出版物何时是西班牙语(或中文等)另一个版本。

我想使用:through关联,以便关系是对称的,例如如果英文Factsheet A有西班牙文版本的事实表B,那么类似的Factsheet B有英文版Factsheet A.

以下是我的模特:

class Factsheet < ActiveRecord::Base
  has_many :publications_language_relationships
  has_one :en, :through  => :publications_language_relationships
  has_one :es, :through  => :publications_language_relationships
  has_one :zh, :through  => :publications_language_relationships #zh = Chinese

  # other stuff
end

和...

# Table name: publications_language_relationships
#
#  en_id      :integer
#  es_id      :integer
#  zh_id      :integer
#
class PublicationsLanguageRelationship < ActiveRecord::Base
  belongs_to :en, :class_name => 'Factsheet'
  belongs_to :es, :class_name => 'Factsheet'
  belongs_to :zh, :class_name => 'Factsheet'
end

但是当我启动一个Rails控制台来检查它是否有效时......

$ fs = Factsheet.last
=> #<Factsheet id: 5, title: "Despu\xC3\xA9s de un diagn\xC3\xB3stico de c\xC3\
xA1ncer de seno: Con...", backend_code: "fs_after_bc_diagnosis_es", language: 
"es", created_at: "2010-11-30 21:23:01", updated_at: "2010-12-06 16:13:23">

$ fs.en
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: publicati
ons_language_relationships.factsheet_id: SELECT "factsheets".* FROM "factsheets"
 INNER JOIN "publications_language_relationships" ON "factsheets".id = "publicat
ions_language_relationships".en_id WHERE (("publications_language_relationships"
.factsheet_id = 5)) LIMIT 1

所以我的协会有些不对劲,但我不太确定是什么。想法?

此外,这甚至是数据的合理设计,还是我应该采取不同的做法?

1 个答案:

答案 0 :(得分:1)

我没有测试过这个解决方案,但我认为你想要采用的一般架构方向并非真正通过:通过关系,而是类似:

class Factsheet < ActiveRecord::Base
  has_many :publications_language_relationships

   named_scope :translation, lambda { |trans|
      { :conditions => ["publications_language_relationships = ?", trans.to_s ] , 
        :joins => :publications_language_relationships 
      }
    }

  # other stuff
end

class PublicationsLanguageRelationship < ActiveRecord::Base
  belongs_to :fact_sheet
end

然后,我认为你会在你的控制器/视图中调用这样的翻译:

#controller
def show
   @fact_sheet = FactSheet.find( params[:id] ) # to load up the FactSheet
end

#view (to get the right translation)
@fact_sheet.translation(:en) #for english

我不认为这是绝对正确的,但无论如何它应该让你走上正轨。