link
は2つのcomponents
:componenta_id
とcomponentb_id
を持っています。この目的のために、私が持っているLink
モデルファイル内:複合フィールドの一意性のためにこの複雑な検証をモデル化する方法
belongs_to :componenta, class_name: "Component"
belongs_to :componentb, class_name: "Component"
validates :componenta_id, presence: true
validates :componentb_id, presence: true
validates :componenta_id, uniqueness: { scope: :componentb_id }
validates :componentb_id, uniqueness: { scope: :componenta_id }
そして、移行ファイル内:
create_table :links do |t|
t.integer :componenta_id, null: false
t.integer :componentb_id, null: false
...
end
add_index :links, :componenta_id
add_index :links, :componentb_id
add_index :links, [:componenta_id, :componentb_id], unique: true
が質問:このすべての作品。今度は、componanta
とcomponentb
の組み合わせを注文に関係なく一意にしたいと思います。したがって、どのコンポーネントがcomponenta
で、どちらがcomponentb
であるかにかかわらず(すべて同じリンクですが、2つの同じコンポーネント間のリンクです)。したがって、以下の2つのレコードは同じリンクを表しているため、一意ではないため、許可しないでください。
- componenta_id = 1; componentb_id = 2
- componenta_id = 2; componentb_id = 1
この一意性検証を作成するにはどうすればよいですか?私はモデルバリデーションを行っていますが(下記参照)、マイグレーション/ dbレベルでバリデーションを追加する必要があるかどうか、またどのように検証する必要があるのだろうか?
私は以下のコードでの作業モデルの検証を持っているモデルの検証
:
1. test "combination of two links should be unique" do
2. assert @link1.valid?
3. assert @link2.valid?
4. @link1.componenta_id = 3 #@link2 already has combination 3-4
5. @link1.componentb_id = 4
6. assert_not @link1.valid?
7. @link1.componenta_id = 4
8. @link1.componentb_id = 3
9. assert_raises ActiveRecord::RecordNotUnique do
10. @link1.save
11. end
12.end
次のテストは上記の作品を確認
before_save :order_links
validates :componenta_id, uniqueness: { scope: :componentb_id }
private
def order_links
if componenta_id > componentb_id
compb = componentb_id
compa = componenta_id
self.componenta_id = compb
self.componentb_id = compa
end
end
移行/ db検証:
セキュリティの追加レベルとして、このための検証をdbレベルで組み込む方法もありますか?それ以外の場合は、データベースにcomponenta_id = 1 ; componentb_id = 2
とcomponenta_id = 2 ; componentb_id = 1
の両方のレコードを書き込むこともできます。
を(http://stackoverflow.com/questions/635937/how-do-i-specify-unique-constraint-for-multiple-columns-in-mysql)多対多の関係を作成することです: '多くを持っている:components' 'validates_length_of:components、maximum:2' – skahlert