1

我有以下表格

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被调用时,我无法将 NULL 插入表关键字的“STATUS_ID”中

注意:我无法更改任何 DDL

4

2 回答 2

2

你弄错方向了。它应该是关键字 belongs_to 状态。一般规则是具有外键列的模型属于另一个模型。

于 2012-12-27T19:01:34.080 回答
2

正如 dstarh 所说,外键关联是倒退的。在您的模型中,您应该只需要:

class Keyword < ActiveRecord::Base
  has_one :keyword_status
end

class KeywordStatus < ActiveRecord::Base
  belongs_to :keyword, :foreign_key => "status_id"
end

为协会工作。此外,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

我使用了 a has many 作为关联,因为从上面所说的看来,一个关键字可以共享另一个关键字所具有的状态。这也意味着您必须执行以下操作:

KeywordStatus.first.keywords = KeywordStatus.first.keywords.push(keyword)
KeywordStatus.save

代替:

keyword.keyword_status = KeywordStatus.first

它的运行方向与您想要的相反。正如您所看到的,这可能会变得非常混乱,所以如果可能的话,我建议编写一个迁移来更改您的表(如果这是问题,可以对具有现有数据的表执行此操作)。我再次希望这会有所帮助!

于 2012-12-27T19:57:10.130 回答