2014-03-19 44 views
0

我有一个类别模型。我想确保用户不会将重复的类别名称添加到他/她的类别列表中。before_validation防止重复的类别名称

这里是我的类模型:

class Category < ActiveRecord::Base 
    belongs_to :user 

    validates :name, presence: true 
    validates :user_id, presence: true 
    before_validation :validate 

    private 
    def validate 
     errors.add(:name, "is already taken") if Category.where("name = '?' AND user_id = ?", self.name, self.user_id).any? 
    end 
end 

这里是我的RSpec测试:

it "is invalid with duplicate name for same user" do 
    existing_category = Category.first 
    new_category = Category.new(:name => existing_category.name, :user_id => existing_category.user_id) 
    expect(new_category).to have(1).errors_on(:name) 
end 

我应该使用before_save或before_validate?另外,我不确定如何写这个。我猜如果检测到重复,我想为:name添加一个错误。以上是我的尝试,但似乎没有让它通过,有什么明显的错误?另外,这是添加自定义验证的好习惯吗?

回答

5

这里有一个更简单的实现你的目标 - 这样你可以使用scope选项validates_uniqueness_of验证的:

validates_uniqueness_of :name, scope: :user_id 

你的规格失败,因为它有一个错误。它预计new_category有错误,但它不会在此对象上运行验证。为此,您只需添加:

new_category.valid? 

之前expect#...行。

+0

不明白为什么这是downvoted。如果仅仅是因为Marek没有注意到用户部分,但现在它已经更新,这正是OP想要的。 –

+0

@Baloo downvote已被删除。 :) –

+0

嗨。我已将您的建议添加到模型中,谢谢。当我在rails控制台中运行describe块时,它似乎完成了这项工作。大! - 我想我的测试中有一个错误,但我无法弄清楚哪里/为什么。有什么明显的我做错了吗? – Martyn