I don't think update_attribute
is going to be useful as it will replace the array with the new value rather than append to it (but see better explanation below in --Update-- section).
I'm not sure what best practices are here, but this should work to just add something if it isn't already there:
question.tags << :ruby unless question.tags.include?(:ruby)
question.save
I would write a custom method on the Question model to manage adding tags and checking for uniqueness:
def add_tag(tag)
if tags.include?(tag)
# do whatever you want to do when tag isn't unique
p "#{tag} is already in tags!"
else
tags << tag
save
end
end
Then call it with question.add_tag(:ruby)
.
-------------------- Update -----------------------
If this doesn't work, there could be an issue with ActiveRecord not recognizing the field has changed (although it seems to work OK in Rails 4.2).
These links explain the issue:
New data not persisting to Rails array column on Postgres
http://paweljaniak.co.za/2013/07/28/rails-4-and-postgres-arrays/
As they explain, you can use update_attribute
here, but you need to replace the entire array rather than push a value onto it, like this:
question.update_attribute(:tags, question.tags << tag)
You should also be able to force ActiveRecord to consider the attribute updated by including will_change!
like this:
def add_tag(tag)
if tags.include?(tag)
# do whatever you want to do when tag isn't unique
p "#{tag} is already in tags!"
else
tags_will_change!
tags << tag
save
end
end