0

has_many :throughUserLocations 結合テーブルを使用して、User モデルと Location モデルの間に双方向の関連付けを実装しようとしています。これにより、組み込みの ActiveRecord メソッドを使用してユーザーの場所を設定できるようになります。@user.locations = [<Location 1>, <Location 2>, ...]. 私の目標は、場所をユーザーに個別に関連付けるのではなく、ユーザーが別のフィールドを介して一度に 1 つまたは複数の場所を追加および削除できるようにすることです:zip_code。つまり、ユーザーが郵便番号を追加すると、ActiveRecord は単一のレコードを UserLocations に挿入する必要があります ( のようなものINSERT INTO user_locations (user_id, zip_code) VALUES (1, 12345))。次に、@user.locationsが呼び出されると、ActiveRecord が参加し:zip_code、一致する場所を取得する必要があります。私の現在の実装は機能INSERTしますが、郵便番号に関連付けられた場所ごとに UserLocations への 1 つが生成されます。

class User < ActiveRecord::Base
  has_many :user_locations
  has_many :locations, through: :user_locations
end

class UserLocation < ActiveRecord::Base
  belongs_to :user
  belongs_to :location, primary_key: :zip_code, foreign_key: :zip_code
end

class Location < ActiveRecord::Base
  has_many :user_locations, primary_key: :zip_code, foreign_key: :zip_code
  has_many :users, through: :user_locations
end

私が試したこと:

  • validates_uniqueness_of :zip_code, scope: :user_id- 検証エラーをスローし、すべてのレコード作成を防止します
  • has_many unique: true- DB クエリの重複を防止しません
  • add_index unique: truefor (user_id, zip_code)- 少なくとも重複するエントリが作成されるのを防ぎますが、不要なクエリを完全に防ごうとしています

このような質問をガイダンスとして使用しても、私はこれ以上近づくことができませんでした. ユーザーの場所を取得/設定するために独自の方法を使用せずに、私がやろうとしていることは可能ですか?

4

3 に答える 3

0

関連付けが正しく設定されているようです。

レールに関連付けがあり、次のhas_manyようなことをしたい場合:

@user.locations = [<Location 1>, <Location 2>, ...]

Rails はINSERT、配列内の各場所に対して個別のステートメントを作成しますが、大量DELETEの処理を行います。一括ステートメントを実行したい場合は、独自のコードをロールするか、 activerecord-import gemINSERTを調べてこれを行う必要があります。

重複に関しては、上記のコードのみを実行している場合、その場所の配列に重複がない限り、重複レコード エラーは発生しないはずです。重複がある場合はuniq、最初に呼び出す必要があります。

于 2013-08-02T10:18:41.693 に答える