我有以下表格
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
和它中断的代码(关键字状态由fixture填充)
keyword = Keyword.new
keyword.description = "keyword#{n}"
keyword.keyword_status = KeywordStatus.first
keyword.save
当keyword.save
被调用时,i get不能在表上的'STATUS_ID'中插入NULL
注意:我不能更改任何DDL
正如starh所说,外键关联是反向的。在你的模型中,你只需要:
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
希望这对你有帮助!
Update 2:既然表不能改变关联,那么关联就有点向后了。我建议:
class Keyword < ActiveRecord::Base
belongs_to :keyword_status
end
class KeywordStatus < ActiveRecord::Base
has_many :keywords, :foreign_key => "status_id"
end
我使用a has many作为关联,因为从已经说过的情况来看,似乎一个关键字可以共享另一个关键字的状态。这也意味着您必须执行如下操作:
KeywordStatus.first.keywords = KeywordStatus.first.keywords.push(keyword)
KeywordStatus.save
代替:
keyword.keyword_status = KeywordStatus.first
它的作用方向与你想要的相反。正如你所看到的,这可能会变得非常混乱,所以如果可能的话,我建议写一个迁移来改变你的表(这可以为有现有数据的表,如果这是问题)。再次,我希望这有助于!
你看错方向了。它应该是关键字belongs_to状态。一般规则是,具有外键列的模型属于另一个模型。