2012-04-19 48 views
0

我的Tag模型对属性name有一些验证。在其他所有情况下都很好。但是当我通过这种方式拨打find_or_create_by_name`find_or_create_by`方法正在跳过模型验证。为什么?

# The last value of this string (by coma) is empty. 
# So this record should not be saved. 
tags_line = 'ruby, javascript, ' 

tags_line.split(',').each do |tag_name| 
    tag = Tag.find_or_create_by_name(tag_name.strip) do |new_tag| 
    new_tag.update_attribute :user_id, member.user.id 
    end 

    # Just append tag to this model 
    # through `has_and_belongs_to_many :tags` 
    tags << tag if tag 
end 

但是这个空标签甚至被保存。那么,在这段代码中可能会出错?

注:当我删除块,它的工作原理:

... 
tags_line.split(',').each do |tag_name| 
    # This way, invalid tag will not be created. 
    tag = Tag.find_or_create_by_name(tag_name.strip) 
    tags << tag if tag 
end 

回答

1

问题是由模型中的属性:name受保护的事实引起的。因此,正如Rails Doc所说:

如果 尚不存在,可以使用相同的动态查找器样式创建对象。这个动态查找器被调用 find_or_create_by_并且将返回该对象,如果它已经存在并且 否则创建它,然后返回它。 受保护的属性不会被设置为 ,除非它们在块中给出。

固定的代码是...

tags_field.split(',').each do |tag_name| 
    tag_name.strip! 

    tag = General::Tag.find_or_create_by_name(tag_name) do |new_tag| 
    # :name is attr_protected 
    new_tag.name = tag_name 
    new_tag.user_id = member.user.id 
    end 

    tags << tag if tag 
end 
0

在最后一次迭代变量具有字符串“”,也就是一个空白。

尝试

tags << tag unless tag.strip.blank? 

只要你使用Ruby on Rails的工作,我怀疑,作为空白?是一个导轨扩展。 否则

tags << tag unless tag.strip.empty? 

编辑:

update_attribute不运行验证。请参阅this

+0

它可以为空值工作,但我想验证格式,长度等。所以我寻找这个问题的根源,避免重复的验证。 Tks – 2012-04-19 16:29:34

+0

你说得对,对不起。误解了你的问题。我在那里添加了更多信息 – Christian 2012-04-19 16:40:28

1

,或者您可以使用以下类型的方法的链接,如果你跳过,而该块

tags_field.split(',').each do |tag_name| 
    tag_name.strip! 

    tag = General::Tag.find_or_create_by_name_and_user_id(tag_name, member.user.id) 

    tags << tag if tag 
end