2017-10-12 6 views
1

requester_idaccepter_idの表friendships内で双方向の一意性を確保する必要があります。考慮すべき解決策としてRailsの移行でGREATESTとLEASTを使用するにはどうすればよいですか?

Table: friendships 

requester_id | accepter_id 
-------------------------- 
      1 |   2 
      2 |   1 <-- this should not be possible 

、私はこのアプローチを見つけた:Postgresql enforce unique two-way combination of columns私はRailsのマイグレーションを記述しようとしています

create unique index ifriendz on friendz(greatest(from_id,to_id), least(from_id,to_id)); 

(私は私もプレーンなSQLを使用することができます知っているが、私は持っていたいですそれはきれいです)。

これは私のコマンドを書き直そうとしたものです。それは動作しません。

class AddBidirectionalUniqueConstraintToFriendships < ActiveRecord::Migration 
    def change 
    add index :friendships, greatest[:requester_id, :accepter_id], least[:requester_id, :accepter_id], unique: true 
    end 
end 
+0

私はRailsのActiveRecordのについての事を知らないが、それは他のほとんどのORMフレームワークのようであれば、それはおそらくほとんどがANSI風味に制限されていますSQL機能。 「最大」および「最小」機能は、データベース特有のものです。 PostgresとMySQLはそれをサポートしますが、すべてのデータベースをサポートしません。だからあなたがしようとしていることは不可能かもしれません。 –

答えて

3

executeコマンドを使用して任意のSQLコマンドを実行できます。例えば

class AddBidirectionalUniqueConstraintToFriendships < ActiveRecord::Migration 
    def up 
    execute <<-SQL 
     create unique index ifriendz on friendz(greatest(from_id,to_id), least(from_id,to_id)); 
    SQL 
    end 

    def down 
    execute <<-SQL 
     drop index ifriendz; 
    SQL 
    end 
end 

`` `

+0

ありがとうございます。これはMySQLとPostgreSQLでのみ利用可能であると考えるときれいですか? – Steven

+0

これでは不十分です。 'db/schema.rb'は' db/structure.sql'にも切り替わらない限り、適切なインデックスを含みません。 –

+0

muが正しいかどうかは 'config/application.rb'で' config.active_record.schema_format =:sql'を 'db/structure.sql'を使うように設定したいでしょう –

関連する問題