I have a Tag model:
class Tag < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
has_many :posts, :through => :taggings
has_many :subscriptions
has_many :subscribed_users, :source => :user, :through => :subscriptions
end
and a Post model:
class Post < ActiveRecord::Base
attr_accessible :title, :content, :tag_names
belongs_to :user
has_many :taggings, :dependent => :destroy
has_many :tags, :through => :taggings
attr_writer :tag_names
after_save :assign_tags
def tag_names
@tag_names || tags.map(&:name).join(' ')
end
private
def assign_tags
return if @tag_names.blank?
@tag_names.split(" ").each do |name|
tag = Tag.find_or_create_by_name(name)
self.tags << tag unless tags.include?(tag)
end
end
end
The assign_tags method stores the saved tags in :tag_names and displays it in an input field in this fashion: tag1 tag2 tag3 (values are separated by spaces).
views/posts/_form.html.erb:
<div class="field">
<%= f.label :tag_names %><br />
<%= f.autocomplete_field :tag_names, autocomplete_tag_name_posts_path, :"data-delimiter" => ' '%>
</div>
As you can see, assign_tags, enables me to add/push tags to tag_names. But if I delete a tag from the input field and save. The tag will still show up.
Any suggestions to help me solve this issue?
(Maybe tag_names should just empty itself before the tags are pushed in. But no idea how to code that).
Before assigning tags, you’ll want to clear the tags for that item. e.g.
Update:
Or, a method that will hit the database a bit less:
If you wanted to get really crazy with the write-less-do-more paradigm, you could do:
Alternatively, I’d recommend looking into the acts-as-taggable-on gem.