2016-07-20 3 views
0

私は、地域と国のためのRails移行を作成しています。アイデアは、各国のために同じ名前の複数の州を許可することはできないということです。
マイcreate_provincesの移行は、次のとおりです。Railsの移行でのhas_manyの一意性(スルーなし)

class CreateProvinces < ActiveRecord::Migration 
def change 
    create_table :provinces do |t| 
     t.string :name 
     t.references :country, index: true, foreign_key: true 
    end 
end 


私country.rbは次のとおりです。

class Country < ActiveRecord::Base 
    has_many :provinces, :uniq => true 
end 

私province.rbは次のとおりです。

country.rbで :uniq => true
class Province < ActiveRecord::Base 
    belongs_to :country 
    private 
    validates_presence_of :country 
    validate :canada_or_usa? 
    validates_presence_of :name 
    validate :in_right_country? 
    validates_associated :country 
    def canada_or_usa? 
    errors.add(:country, "can only add province for Canada or the United States") unless (country.name == "Canada" || country.name == "United States") 
    end 
    def in_right_country? 
    if country.name == "Canada" 
     errors.add(:name, "Name must be the name of a province in Canada") unless (DataHelper::canada_provinces_with_caption.include? name) 
    end 
    if country.name == "United States" 
     errors.add(:name, "Name must be the name of a province in the United States") unless (DataHelper::usa_provinces_with_caption.include? name) 
    end 
    end 
end 

、私はuniqは既知のキーではありません。他の質問につきましてはthroughも使用していないことにご注意ください。各国が同じ名前の2つの州を持つことができないようにする方法はありますか?お使いの省モデルで

答えて

0

まず、:uniq => trueは、データの一意性を偽造するだけです。地方にsome_country_instance.provincesを追加すると、クエリにDISTINCT句が追加されます。これにより、ある国に同じ​​名前の2つの州を挿入することができます。私はそれを削除することをお勧めします。あなたはだまされたくありません。

実際に行うべきことは、[province_id、province_name]列をテーブルの主キーとして追加することです。私はcountriesに外部キー列としてあなたのテーブルprovincesありcountry_idを想定してい

... 
def change 
    add_index :provinces, [:country_id, :name], unique: true 
end 
... 

、およびnameコラム省名前を保持する:

あなたはこのコードの移行とそれを達成することができます。私が提案するモデルのデータを検証する

:それと

... 
validates :name, uniqueness: { scope: :country_id, 
      message: "My world my rules. Country cannot have provinces with same name." } 
... 

あなたがエレガントに数行のコードであなたの仕事を達成するとRailsフレームワークをフル活用しましょう。

0

あなたはこれを使用すると、同じ名前ではなく、単一の国内の州を持ってできるようになります

validates uniqueness: { scope: :country } 

を追加する必要があります。

0

正しい構文は、しかし、これは単に関連付けを定義しているし、実際にあなたのデータベースへの入力を検証しない

has_many :provinces, -> { uniq } 

だろう。あなたがSQLを見れば、あなたは何かのように見えます。

Select distinct provinces from provinces where provinces.country_id = ''; 
関連する問題