2011-08-05 7 views
0

foreign_keyポリシーを守っていないモデルに問題があります。has_manyに特定の:foreign_keyを使用させる方法

キャラクターモデルは、以下のフィールドがあります。 名:文字列 レベル:文字列 realm_id: レルムをint型の整数

class Character < ActiveRecord::Base 
    belongs_to :realm 

end 

は私のレルムモデルは次のようになります。

class Realm < ActiveRecord::Base 
    has_many :characters, :foreign_key => "realm_id" 

end 

しかし、キャラクターモデルがrealm_idではなくforeign_keyとして:realm列を使用するようになっているようです。私はそれをどうやって修正するかについての手がかりはない。 realmフィールドを無視し、:realm_idのために移動する他の方法はありますか?列の名前を変更する必要はありませんか?

[明確にするための編集]

キャラクタモデルがrealm_id持っている:整数フィールド。私はforeign_keyを持っていないことを試みましたが、両方の結果は同じです。

ルビー-1.9.2-P136:012> C = Character.new =>#

ルビー-1.9.2-P136:013> c.realm = "Sargeras"

のActiveRecord: :AssociationTypeMismatch:Realm(#2154038240)expected、got String(#2151988680)

foreign_keyを持っているにもかかわらず、それは領域の列を放棄することを拒否します。

[編集2]

レルムコラムはちょうど原因にhas_manyとbelongs_toの関連を引き継ぎます。これまでのところこれを壊す方法はないので、解決方法は列を削除するか(それを取る方法です)、別の名前に変更します。

+0

私はこれを試しましたが、作成した関連付けに基づいて、Realmオブジェクトを参照するCharacterのメソッド "realm"が作成されるため、Characterオブジェクトを作成することすらできません。だから私はc = Character.new(:realm => "wasteland")を呼び出すことができません。なぜなら、文字列ではなく "realm"のRealmオブジェクトを期待しているからです。とにかく、私はあなたのオブジェクトモデルを見るほど、あなたは正しい方法に近づいているのだろうかと思います。なぜキャラクターはrealm_idとrealmの両方を持っていますか?確かにrealm_idに基づいて必要なときにレルム情報を参照し、それをCharacterモデルに格納しないでください。 – JimDaniel

+0

あなたは領域モデルで領域と呼ばれるフィールドについて話しますか?それを別のものと呼んで、外来キーを削除してください – jamesc

答えて

0

標準のRails命名規則に従っているので、:foreign_keyの部分は一切必要ありません。モデル名からrealm_id列を推測する必要があります。私が見

EDIT

。あるモデルで同じ名前の列と関連付けを持つことはできないと思います。最も簡単な解決策は、おそらく "realm"列または "realmname"列に名前を変更することでしょう。

+0

私はそれを更新しました。私はforeign_keyを削除しましたが、それはただ拒否します! – roloenusa

+0

私の答えを編集しました。 – Thilo

+0

ありがとうございます...私はそれが唯一の方法だと思っています...私は本当にforeign_keyの追加によって領域フィールドを無視することを強く望んでいました。私は、レルムを含む別のソースからこのデータをインポートしているので、データを一貫性があり、きれいに保つように変更しないでください。いずれにしても、名前やIDを保存するように変更する必要があります。 あなたの投稿はとても役に立ちました。ありがとうございました! – roloenusa

1

あなたのキャラクターテーブルにrealm_idの列があることを確認しましたか?それを確認してから、foreign_key => 'realm_idを取り除いてください。全く必要ありません。あなたのプログラムは、これらの両方が完了したらうまくいくはずです。

+0

はい、私は..それはまだそれが好きではありませんでした。 – roloenusa

+0

あなたの間違いを発見しました。これは次のとおりです: ** ruby​​-1.9.2-p136:013> c.realm = "Sargeras" ** ** ActiveRecord :: AssociationTypeMismatch:レルム(#2154038240)、ストリング(#2151988680)* * ** realm **モデルに属する** character **モデルを持っているため、オブジェクトを割り当てる必要があります。したがって、実行する必要があります ** @ realm_obj = Realm.new **、 ** c.realm = @ realm_obj ** オブジェクトを割り当てる必要があるときに文字列を割り当てています。 もう一つは、あなたの割り当ては、実際にする必要があります: レルムモデルとして** realm_obj.character = @ character_obj ** ** **あなたはまだ疑問や問題の両方を逃している – rookieRailer

+0

キャラクタモデルを持っています。私はそれが欲しいとわかっていて、私はそれを文字列(それは元の質問に投稿されたもの)にしています。しかし、それは私がすでに親にそれを結びつけるのに使うrealm_idを持っているので、私が想定していた動作ではありません。それで、なぜ私はフィールド自体を検出するのではなく、外部キーを使用するように強制しようとしていたのですか? 私は大変感謝していますが、回答する前に全質問とコメントを読むことを検討してください。 :) – roloenusa

0

belongs_to :realmは、getterおよびsetterとして使用されるrealmおよびrealm=というメソッドを作成します。つまり、ActiveRecordが属性としてデータベース列を公開するために使用するmethod_missingマジックは、Character#realmを実行しても、そのメソッドが実際には存在しないため、決して起動されません。

あなたは、データベース内のレルムの列の名前を変更しないようにしたい場合は、別の名前の下に手動でフィールドの属性アクセサを作成することができます。

class Character < ActiveRecord::Base 
    def realm_name 
    self['realm'] 
    end 

    def realm_name=(value) 
    self['realm'] = value 
    end 
end 

あなたはまだ、データベース内のレルムの列があるでしょう。この道を別の名前でもRubyの属性にアクセスすることができます。しかし、これはいい考えではありません。領域名はCharacter#realm_nameCharacter.realm.nameの両方に複製されます。

私はrealm列を捨て、代わりに、データソースからインポートするとき、私はRealmオブジェクトを使用していることを確認します:

character.realm = Realm.find_by_name('Sargeras') 

あなたが利用可能な唯一のレルムデータ、それは理にかなっているだろうと道を。 Realmモデルの

+0

私はかなり同じ結論に達し、同じソリューションを実装しました。それは同じことをプロに見せてもらうことです:) 最終的にはrealm列をディッチし、ビルドまたは作成を通じて挿入できるように、ハッシュを消去するいくつかのメソッドを実装しました!私はまだ、foreign_keyが領域フィールドを無視するように強制すべきだと主張/賛成する。どのように間違っているのか分かりませんが、foreign_keyリクエストを尊重しないと意味がありません。 – roloenusa

+0

'foreign_key'オプションは、関連付けられたモデルを検索するときにActiveRecordにどの列を使用するかを指示するために使用されます。それは協会の名前を変更するものではありません。これは、関連の名前、つまりhas_manyまたはbelongs_toの後の単語を変更することで行います。 'realm.characters'を実行したときに指定された' foreign_key' *が使用され、 'FROM characters WHERE realm_id = 42'というSQLを生成するActiveRecordが生成されます。これは、デフォルトとまったく同じであるため、オプションは必要ありません。 –

関連する問題