12

私は次のものを持っています:

class User < ActiveRecord::Base
  has_one :car, :class_name => 'Car', :foreign_key => 'user_id'

class Car < ActiveRecord::Base
  belongs_to :worker, :class_name => 'User', :foreign_key => 'user_id'

基本的にユーザーとクルマは1対1の関係です。

私が望むのは、ユーザーが 1 台だけの車を持つことができるようにすることです。これは、自分に割り当てられた車を作成すると、2 番目の車を作成できないという事実を意味します。

これはどのように行うことができますか?

4

3 に答える 3

21

これを達成するには、確かにいくつかの異なる方法があります。user_id がテーブル内で一意になるように、そのテーブルに複合キー インデックスを作成することをお勧めします。これにより、一度だけ存在することが保証されます。移行では、次のように書くことができます。

add_index(:cars, :worker_id, :unique => true)

最初の引数はテーブル名です (これは通常、クラス名の複数形であることを忘れないでください)。フィールド名は 2 番目に来ます。一意の true は、余分な行を挿入できないようにするものです。

注: これはデータベース レベルの制約です。検証でキャッチされなかったためにこれをヒットすると、エラーがスローされます。

このソリューションに加えて、Car モデル自体に検証を追加する必要があります。

validates_uniqueness_of :worker_id, message: "can not have more than one car"

「Worker ID can not have multiple car」のようなエラーが表示されます。これの「Worker ID」セクションをカスタマイズすることをお勧めします。その方法については、この投稿を参照してください。

確かに db 制約を行う必要はありませんが、他の誰かが DB に挿入する場合に備えて、それは良い考えです。そうしないと、Rails に関する限り、「無効な」データになります。

于 2013-03-08T00:53:31.373 に答える
15

リレーションシップの定義を少し変更します。

class User < ActiveRecord::Base
  has_one :car

class Car < ActiveRecord::Base
  belongs_to :worker, :class_name => 'User', :foreign_key => 'user_id'

そして、あなたが探しているものを確立します。参照: http://guides.rubyonrails.org/association_basics.html#the-has-one-association

于 2013-02-26T20:32:47.560 に答える
1

ユーザーが車を追加しようとする前に、なぜテストしないのですか?

if worker.car
 raise "sorry buddy, no car for you"
else
 car = Car.create(user_id: worker.id)
end
于 2013-02-26T20:38:30.897 に答える