0

My Tag model has some validations for attribute name. It's wroking fine in all other cases. But when I call find_or_create_by_name by this way:

# 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

But this empty tag is even being saved. So, can be something wrong in this code?

NOTE: When I remove the block, it works:

...
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
Edison Machado
  • 1,410
  • 19
  • 29

3 Answers3

1

The problem was caused by the fact that attribute :name is protected in model. So, as the Rails Doc says:

The same dynamic finder style can be used to create the object if it doesn’t already exist. This dynamic finder is called with find_or_create_by_ and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won’t be set unless they are given in a block.

The fixed code is...

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
Edison Machado
  • 1,410
  • 19
  • 29
1

or you could use the following type of method chaining if you rather skip the block

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
mhenrixon
  • 6,179
  • 4
  • 40
  • 64
0

In the last iteration tag has the string ' ', that is, a whitespace.

Try

 tags << tag unless tag.strip.blank?

as long as you're working with Ruby On Rails, which I suspect, as blank? is a rails extension. Else

 tags << tag unless tag.strip.empty?

Edit:

update_attribute does not run validations. See this

Community
  • 1
  • 1
Christian
  • 1,258
  • 10
  • 11
  • It may work for empty values, but I want to validate format, length, etc. So Im searching for the root of this problem, avoiding repeated validations. Tks – Edison Machado Apr 19 '12 at 16:29
  • You're right, sorry. Misinterpreted your question. I added some more info there – Christian Apr 19 '12 at 16:40