2013-02-26 12 views
5

Railsの私は、次のしている1対1の関係

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の関係です。

私が欲しいのは、ユーザーが唯一の車を持つことができることです。それは、彼が割り当てられた車を作るなら、彼は第二の車を作ることができないという事実を意味します。

どうすればいいですか?

+0

ここhttp://rubyonrailsthrissur.wordpress.com/2012/07/19/one-to-one-relation-in-rails/最も実用的な説明 – montells

答えて

2

なぜユーザーが車を追加しようとする前にテストしてみませんか?

if worker.car 
raise "sorry buddy, no car for you" 
else 
car = Car.create(user_id: worker.id) 
end 
+0

ありがとう、それは動作します。 – cgf

14

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

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

最初の引数はテーブル名です(これは一般的にクラス名の複数形バージョンです)。フィールド名は2番目に来ます。独自の真実は、余分な行を挿入できないことです。

注:これはデータベースレベルの制約です。バリデーションがキャッチしなかったためにヒットすると、エラーが発生します。

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

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

このエラーは、「ワーカーIDに複数の車を割り当てることはできません」というようなものがあります。この「ワーカーID」セクションをカスタマイズすることをお勧めします。これを行う方法については、postを参照してください。

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