0

我有3種型號:Rails的嵌套屬性:validates_uniqueness_of不起作用

class UserLanguage < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :language 
end 

class Language < ActiveRecord::Base 
    has_many :user_languages 
    has_many :users, :through => :user_languages 
end 

class User < ActiveRecord::Base 
    has_many :user_languages, :dependent => :destroy 
    has_many :languages, :through => :user_languages 
    accepts_nested_attributes_for :user_languages, :allow_destroy => true 
end 

我使用nested_form gem,以幫助用戶選擇的語言(),他們可以說在該CRUD工作正常。

但是,我無法驗證UserLanguage的唯一性。我嘗試這2語法,但他們並沒有爲我工作:爲user_languages表

validates_uniqueness_of :language_id, scope: :user_id 
validates :language_id, :uniqueness => {:scope => user_id} 

我的架構:

create_table "user_languages", force: :cascade do |t| 
    t.integer "user_id" 
    t.integer "language_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    add_index "user_languages", ["language_id"], name: "index_user_languages_on_language_id", using: :btree 
    add_index "user_languages", ["user_id"], name: "index_user_languages_on_user_id", using: :btree 

我應該怎麼做,以確保一個用戶只能選擇一種語言一次?說,如果我在下拉菜單中選擇英語,我的第二個英語將不會被保存(重複)並被拒絕。

回答

0

如果用戶有且只能有一個語言,那麼你可以改變基數的車型之間:

class Language < ActiveRecord::Base 
    has_many :users 
end 

class User < ActiveRecord::Base 
    has_one :language 
end 

然後定義您的用戶將只能有一次一個語言,你的整體模式將簡單。

你可以閱讀更多有關活動記錄協會和基數in this Association Basics guide

+0

謝謝你的幫助。真的很感激它。 –

0

這是我做的最後:

class UserLanguage < ActiveRecord::Base 

    belongs_to :user 
    belongs_to :language 

    def self.delete_duplicated_user_languages(user_id) 
     user_languages_ids  = UserLanguage.where(user_id: user_id).pluck(:language_id).sort 
     duplicate_language_ids = user_languages_ids.select {|language| user_languages_ids.count(language) > 1} 
     duplicate_language_ids.uniq! 
     keep_this_language = [] 
     duplicate_language_ids.each do |language_id| 
      keep_this_language << UserLanguage.find_by(user_id: user_id, language_id: language_id).id 
     end 
     single_language = user_languages_ids.select {|language| user_languages_ids.count(language) == 1} 
     single_language.each do |language| 
      keep_this_language << UserLanguage.find_by(user_id: user_id, language_id: language).id 
     end 
     UserLanguage.where(user_id: user_id).where.not(id: keep_this_language).destroy_all 
    end 

end 

我保存所有UserLanguage第一個,後來刪除(重複者)。