Stories with many tags, tags with many stories, has_and_belo


#1

Hi,

I began experimenting with habtm relationships, and so I created a
stories table, a tags table, and a stories_tags table referencing the
former 2.

When I create a “story”, I want to add several tags to it. Then, the
model should create those tags and link them to the respective stories,
and for the tags that already exists, just link them to the story.

I tried something like this (snippets):

class Tag < ActiveRecord::Base
def self.create(taglist)
tags = Array.new
count = 0
taglist.split(/,/).each do |tag|
tags[count] = Tag.new(:name => tag.chop.downcase)
count += count
end
end
end

class StoriesController < ApplicationController
def create
@tags = Tag.create(params[:tags][:tags])
params[:story][:tags] = @tags
@story = Story.new(params[:story])
render_text @tags.length
end
end

params[:tags][:tags] can be something like “cats, dogs, pets”. With that
code, I get: “Tag expected, got String”.

I suppose I could save each tag individually, retrieve it’s id, and
create the rows in the link table, myself, but this is Rails, so I’m
sure there’s a much better way.

Could you help me out?

Thanks!

Ivan V.


#2

While the acts_as_taggable mixin might work for you here, it should also
be noted that ActiveRecord’s latest version includes the ability to
create find_or_create_by_X methods. Because sometimes you want to do a
find or create if doesn’t exist for things other than tag models.

See:
http://weblog.rubyonrails.com/articles/2005/11/07/rails-1-0-rc4-0-14-3-its-the-final-countdown

=?ISO-8859-1?Q?Iv=E1n_Vega_Rivera?= wrote:

Hi,

I began experimenting with habtm relationships, and so I created a
stories table, a tags table, and a stories_tags table referencing the
former 2.

When I create a “story”, I want to add several tags to it. Then, the
model should create those tags and link them to the respective stories,
and for the tags that already exists, just link them to the story.

I tried something like this (snippets):

class Tag < ActiveRecord::Base
def self.create(taglist)
tags = Array.new
count = 0
taglist.split(/,/).each do |tag|
tags[count] = Tag.new(:name => tag.chop.downcase)
count += count
end
end
end

class StoriesController < ApplicationController
def create
@tags = Tag.create(params[:tags][:tags])
params[:story][:tags] = @tags
@story = Story.new(params[:story])
render_text @tags.length
end
end

params[:tags][:tags] can be something like “cats, dogs, pets”. With that
code, I get: “Tag expected, got String”.

I suppose I could save each tag individually, retrieve it’s id, and
create the rows in the link table, myself, but this is Rails, so I’m
sure there’s a much better way.

Could you help me out?

Thanks!

Ivan V.


#3

That will come in handy too! Thanks