Making has_and_belongs_to_many save more elegant


#1

When a user creates a post I also want to save all the tags
associated with it. I do that in the post_controller like this
presently:

def save
@post = Post.new(@params[:post])
@tags = Tag.new(@params[:tags])
@post.user_id = session[:id]

if @post.save
	@tags.title.split(',').each do |tag|
		present_tag = Tag.find_by_title(tag.strip)
		present_tag = Tag.create(:title => tag.strip) if present_tag.nil?
		@post.tags.push(present_tag)
	end

	flash[:notice] = "Successfully Created Post!"
	redirect_to :controller => "home", :action => "index"
else
   		render :action => "new"
end

end

Now I have a couple questions:

  1. Is there an easier way to save both the tags and the post at the
    same time?
  2. Do I need to do the push to save the join table or is there a more
    elegant way or automated way of doing this?
  3. Does the fact that I have to check to see if tag already exist
    change things?

Your feedback is greatly appreciated. I find my solution not that
elegant and would love to find a new one. This is for my site http://
www.soen.info.

Your Friend,

John K.


http://www.soen.info - source of the freshest software engineering
information on the net
http://cusec.soen.info - software engineering conference
http://www.kopanas.com - personal site


#2
            end

            flash[:notice] = "Successfully Created Post!"
            redirect_to :controller => "home", :action => "index"
    else
            render :action => "new"
    end

end

The docs for has_and_belongs_to_many say that a method
collection_singular_id is created to quickly set the IDs:

@article.category_ids = [1,2,3]

So try something like this:

@post.tag_ids = params[:tags][:title].split(’,’).collect do |tag|
Tag.find_or_create_by_title(tag.strip).id
end

For that matter, name the tags text field post[tags] and create this
in your Post model:

class Post < AR::Base
def tags=(tag_string)
self.tag_ids = tag_string.split(’,’).collect do |tag|
Tag.find_or_create_by_title(tag.strip).id
end
end
end


rick
http://techno-weenie.net