我有以下表格
keyword
keyword_id - PK
description
status_id - FK
keyword_status
status_id - PK
description
尝试在AR中对它们进行建模,并且在尝试保存我的测试时,它不会在关键字中保存状态ID。它们被映射为:
class Keyword < ActiveRecord::Base
self.table_name = :keyword
self.primary_key = :KEYWORD_ID
attr_writer :description
attr_writer :keyword_status
has_one :keyword_status, foreign_key: :STATUS_ID
end
class KeywordStatus < ActiveRecord::Base
self.table_name = :keyword_status
self.primary_key = :STATUS_ID
end
以及它破坏的代码(关键字状态由夹具填充)
keyword = Keyword.new
keyword.description = "keyword#{n}"
keyword.keyword_status = KeywordStatus.first
keyword.save
当调用keyword.save
时,我无法在表关键字'STATUS_ID'中插入NULL
注意:我无法更改任何DDL
答案 0 :(得分:2)
你的方向错了。它应该是关键字belongs_to status。一般规则是具有外键列的模型属于另一个模型。
答案 1 :(得分:2)
正如dstarh所说,外键关联是倒退的。在您的模型中,您只需要:
class Keyword < ActiveRecord::Base
has_one :keyword_status
end
class KeywordStatus < ActiveRecord::Base
belongs_to :keyword, :foreign_key => "status_id"
end
让协会工作。此外,在创建关联对象之前使用fixture设置KeywordStatus
对象有点奇怪,但如果这是您需要的行为,则会起作用。另外,为什么不使用外键keyword_id
并让rails为你处理它?
如果您想使用keyword_id
代替status_id
作为外键,请更新:
表格如下:
keyword
id - PK
description
keyword_status
id - PK
keyword_id - FK
description
你的模特:
class Keyword < ActiveRecord::Base
has_one :keyword_status
end
class KeywordStatus < ActiveRecord::Base
belongs_to :keyword
end
希望这有帮助!
更新2:鉴于表格无法更改,关联必须有点倒退。我建议:
class Keyword < ActiveRecord::Base
belongs_to :keyword_status
end
class KeywordStatus < ActiveRecord::Base
has_many :keywords, :foreign_key => "status_id"
end
我使用了很多作为关联,因为从所说的看起来关键字可以共享另一个关键字具有的状态。这也意味着您必须执行以下操作:
KeywordStatus.first.keywords = KeywordStatus.first.keywords.push(keyword)
KeywordStatus.save
而不是:
keyword.keyword_status = KeywordStatus.first
其运作方向与您想要的相反。正如您所看到的,这可能会让人感到非常困惑,所以如果可能的话,我会建议编写一个迁移来更改表(如果这是问题,可以对具有现有数据的表执行此操作)。我希望这有帮助!