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呼び出されると、テーブル キーワードの 'STATUS_ID' に NULL を挿入できません

注: DDL を変更することはできません

4

2 に答える 2

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を使用してレールに処理させてみませんか?

外部キーの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

キーワードは別のキーワードが持つステータスを共有できるように見えるので、関連付けとして has many を使用しました。これは、次のようなことをしなければならないことも意味します。

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

それ以外の:

keyword.keyword_status = KeywordStatus.first

これは、必要な方向とは反対の方向に動作します。ご覧のとおり、これはかなり混乱する可能性があるため、可能な場合は、テーブルを変更するための移行を作成することをお勧めします (これは、既存のデータがあるテーブルで問題がある場合に実行できます)。繰り返しますが、これが役立つことを願っています!

于 2012-12-27T19:57:10.130 に答える