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第一个,后来删除(重复者)。