2011-03-07 20 views
6

私はIDが| patient_id | client_id | activeのテーブルを持っています。レコードはpatient_id、client_idによって一意です。つまり、クライアントごとに1人の患者に1つの登録のみが必要です。通常はそれをプライマリキーにしますが、レールには私のプライマリキーとしてIDがあります。複合主キーを偽装しますか? Rails

これを実行する最善の方法は何ですか?検証?

答えて

8

が鳴ります。私はそうのようなあなたのClientPatientモデルを変更します。これは、ここで説明するように、それはまだ可能競合状態を起こしやすい小規模なアプリケーションに最適ですながら、ため

class Enrollment < ActiveRecord::Base 
    belongs_to :client 
    belongs_to :patient 
    validates_uniqueness_of :patient_id, :scope => :client_id 
end 

は、しかし注意してください:http://apidock.com/rails/v3.0.5/ActiveRecord/Validations/ClassMethods/validates_uniqueness_of「同時実行性と整合性」の下で

そこに記述されているように、データベース内のテーブルに一意のインデックスも追加する必要があります。

  • (それらがインデックス化しているので)これら2つのIDのに基づいて、このモデルによる検証チェックし、任意の検索が高速に実行されます
  • 一意性制約がDB側に施行されますが、これは2直接的なメリットを提供しますまれに競合状態が発生すると、データベースに悪いデータが保存されることはありません。エラーを検出しない場合、ユーザーは500 Server Errorになります。移行ファイルで

次の行を追加します。

add_index :enrollments, [:patient_id, :client_id], :unique => true 

うまくいけば、これは参考になりました:)

編集(固定いくつかの命名問題やカップルの明白なバグ):

それは、その後です探しているデータを簡単に見つけることができます:

Client.find_by_name("Bob Smith").patients 
Patient.find_by_name("Henry Person").clients 
+0

機能:スコープ内で一意でなければならない列を選択しますか?たとえば、validates_uniqueness_of:patient_id、:scope =>:client_idと言ってください。これは「患者IDはclient_idごとに一意でなければなりません」と解釈されますか? –

+0

はい:これはscopeオプションがするものです。コンポジットキーの制約を強制することと本質的に同じですが、そうではありませんか?患者IDが異なる限り、同じ2つのクライアントIDを持つことができます。そして逆に同じ患者IDを2つ持つことができますが、クライアントIDは一致しません。 – nzifnab

+1

: validates_uniqueness_of:patient_id、:scope =>:client_idおよび validates_uniqueness_of:client_id、:scope =>:patient_id同じですか? –

1

検証は(Back them up with a unique index!)で動作しますが、真の複合主キーを取得する方法はありません。本当のコンポジットのプライマリキーが必要な場合は、gem/pluginが必要になります。composite_primary_keysが見つかりましたが、他にもあります。

希望すると便利です。制約を破るレコードを保存しようとしたとき、あなたが適切なフィードバックを得るように、私はActiveRecordの中でそれを行うだろう、あなたの制約を適用するには

class Client < ActiveRecord::Base 
    has_many :patients, :through => :enrollments 
    has_many :enrollments 
end 

class ClientPatient < ActiveRecord::Base 
    belongs_to :client 
    belongs_to :patient 
end 

class Patient < ActiveRecord::Base 
    has_many :clients, :through => :enrollments 
    has_many :enrollments 
end 

:あなたはのモデル関係を持っているよう

関連する問題