Forum: Ruby on Rails making has_and_belongs_to_many save more elegant

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
John Kopanas (Guest)
on 2005-12-28 17:54
(Received via mailing list)
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 Kopanas

--
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
Rick Olson (Guest)
on 2005-12-28 18:33
(Received via mailing list)
>                 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
This topic is locked and can not be replied to.