0

私は2つのモデルを持っています:UserそしてLocation以下のように:

class User < ActiveRecord::Base
  attr_accessible :location, :password, :user_name, :password_confirmation

  validates :location, :user_name, :presence => true
  validates :password, :presence => true, :confirmation => true

  has_one :location, :foreign_key => 'location'

end

class Location < ActiveRecord::Base
  attr_accessible :loc_id, :loc_name

  belongs_to :user, :foreign_key => 'loc_id'
end

モデルにカスタムのforeign_keyを使用していることがわかります。フォームビルダーを使用してユーザーサインアップフォームを作成しましたが、データを送信するとエラーが発生します。

Location(#2170327880) expected, got String

私はフォームの作成に使用simple_formします。関連するコードは次のとおりです。

= f.input :location, :collection => Location.all.collect {|c| [c.loc_name, c.loc_id]}

この問題を解決するにはどうすればよいですか?または、関連付けにデフォルトの外部キーを使用する必要がありますlocation_idか?

ありがとう。

アップデート:

モデルのlocationフィールドの名前をに変更し、次のように削除すると、次のようになります。Userloc_id:foreign_key

class User < ActiveRecord::Base
  attr_accessible :loc_id, :password, :user_name, :password_confirmation

  validates :loc_id, :user_name, :presence => true
  validates :password, :presence => true, :confirmation => true

  has_one :location, :foreign_key => 'location'

end

class Location < ActiveRecord::Base
  attr_accessible :loc_id, :loc_name

  belongs_to :user
end

正常に動作します。Userしかし、私はまだとLocationモデルを関連付ける方法を知りたいです。

PS私はLocationモデルを使用して国コードと国名を保存しますが、これはによって更新されることはありませんUser

4

4 に答える 4

1

外部キーを誤用しているようです。Userモデルでは、justが必要でhas_one :locationあり、locationモデルにはuser_id属性が必要です。ロケーションモデルでは、を記述するだけで済みますbelongs_to :user。外部キーは常に別の(外部)テーブルへのインデックスです。

于 2012-06-08T08:23:01.807 に答える
1

あなたが実際に持っていたいように聞こえます

class User < ActiveRecord::Base
  belongs_to :location
end

class Location < ActiveRecord::Base
  has_many :users
end

これは、ユーザーがlocation_id列を持っていることを意味します。逆の場合(場所のuser_id列)、特定の場所は1人のユーザーにのみ関連付けることができます。レールの方法は、location_idユーザーがロケーションテーブルのid列を「ポイント」することです。別の列を指すようにする場合は、:primary_keyオプションを使用します(この:foreign_keyオプションは、ユーザーの列をlocation_id以外の名前で呼び出す場合に使用します)

フォームに関しては、あなたはできませんf.select :location-フォームはそのような複雑なオブジェクトを転送する方法を知りません。このような場合、location_id属性を制御するようにフォームを設定する必要があります。

= f.input :location_id, :collection => Location.all.collect {|c| [c.loc_name, c.id]}

ロケーションID列がロケーションのloc_id列を参照するというルートをたどる場合は、それを次のように変更する必要があります。

= f.input :location_id, :collection => Location.all.collect {|c| [c.loc_name, c.loc_id]}

個人的には、レールから始めたばかりの場合は、デフォルトを使用します

于 2012-06-09T12:27:05.437 に答える
0
class User < ActiveRecord::Base
  # stuff

  has_one :location    
end

class Location < ActiveRecord::Base
  # more stuff

  belongs_to :user
end
于 2012-06-08T08:30:17.940 に答える
0

最終的に実行したいのが同じ場所にいるすべてのユーザーを選択することである場合は、モデルを少し異なる方法で設定することをお勧めします。現在、各ユーザーはロケーションテーブルに独自のロケーションレコードを持っているため、ロケーションが重複することになり、一意のロケーションについてこれらすべてを検索し、それらからuser_idを抽出する必要があります。

代わりにこれを行う

class User < ActiveRecord::Base
   has_one :placement
   has_one :location, through: :placement
end

class Placement < ActiveRecord::Base
    belongs_to :user
    belongs_to :location
end

class Location < ActiveRecord::Base
    has_many :placements
    has_many :users, through: :placements
end

。移行に関しては、プレースメントには:user_idと:location_idが必要です。現在Locationにある:user_idを削除できます。このコードは、多くのユーザーがいて、多くの一意の場所があり、プレースメントを作成してユーザーを一意の場所に配置していることを示しています。これは、:user_idを持つユーザーが:location_idを持つ場所にいることを示します。また、行を追加することを忘れないでください

add_index :placements, [:user_id, :location_id], unique: true

そのため、ユーザーを1つの場所に複数回配置することはできません。

編集:追加するのを忘れた:ロケーションレコードを取得してlocation.usersを呼び出すだけで、ロケーション内のすべてのユーザーを取得できます

于 2012-06-08T15:53:11.513 に答える