acts_as_taggable and foreign keys

Hi,

I've developed an application last year with rails 1.2.3 and it worked fine on the web server till recently. Not sure what started the problem but I am having trouble with acts_as_taggable gem (which I know has been depreciated).

It was suggested to look into has_many_polymorphs but I ran into problems with updating my database. The database has 3 tables (:products, :tags, :products_tags) and uses foreign keys. The application is based on "Beginning RoR e_commerce". Tags table has 2 columns: id and name.

So, I gave that up on that one and tried to find an easier solution. Other things I looked at: * I installed acts_as_taggable as plugin instead of a gem -- but I'm just not sure what to change in the application in order to get it to work * I installed acts_as_taggable_on_steroids -- but again, I think I ran into the same problem with the foreign keys. This is the error message I get when I try "rake db:migrate"

[code] Mysql::Error: Table 'tags' already exists: CREATE TABLE tags (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `name` varchar(255) DEFAULT NULL) ENGINE=InnoDB [/code]

Would anyone have a solution on how to fix my problem? Thanks in advance, Elle

So, I gave that up on that one and tried to find an easier solution. Other things I looked at: * I installed acts_as_taggable as plugin instead of a gem -- but I'm just not sure what to change in the application in order to get it to work * I installed acts_as_taggable_on_steroids -- but again, I think I ran into the same problem with the foreign keys. This is the error message I get when I try "rake db:migrate"

[code] Mysql::Error: Table 'tags' already exists: CREATE TABLE tags (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `name` varchar(255) DEFAULT NULL) ENGINE=InnoDB [/code]

I assume acts_as_taggable_on_steroids is trying to create a tags table
that you already have. I'd just blow away that migration (after
checking that the table it was trying to create matches the one you
already have.

Fred

Thanks Fred. I did just that. I also dropped my products_tags table because as I understand the 'taggings' table created by the plugin acts as the connector. Now, I don't care about losing that data in this case, I can always enter it manually (and I am happy not to be using a depreciated gem).... but I feel hopeless as I am not sure how to make it work from now on.

What I've done so far is: 1. Installed plugin 2. Added db table: taggings. Already had tags with id and name column. 3. Added acts_as_taggable to my Product class

When I login as admin to try and tag the products manually, I get this error message (when I have both acts_as_taggable and acts_as_taggable_on_steroids plugins installed):

NoMethodError in ProductController#update undefined method `tag_collection_name' for Product:Class

My update method includes the following:

def update     @product = Product.find(params[:id])     @product.tag(params[:tags], :separator => ',', :clear => true)

    if @product.update_attributes(params[:product])       flash[:notice] = 'Product was successfully updated.'       redirect_to :action => 'show', :id => @product     else       load_data       render :action => 'edit'     end   end

private

    def load_data       @categories = Category.find(:all)       @tags = Tag.find(:all)     end

I am just not sure how to make the connection between the tag and the product. Help. Please.

Elle

First off, you're probably asking for trouble by having both installed

Secondly, have you tried just looking at the examples in the acts_as_taggable_on_steroids documentation ?

Fred

First off, you're probably asking for trouble by having both installed

Well, when I deleted acts_as_taggable, I got an error of:

Processing ProductController#update (for 127.0.0.1 at 2008-07-15 18:35:50) [POST]   Parameters: {"commit"=>"Edit", "tags"=>"LS750", "product"=>{...}, "action"=>"update", "id"=>"1", "controller"=>"product"} [...] NoMethodError (undefined method `tag' for #<Product:0x26064fc>):

Secondly, have you tried just looking at the examples in the acts_as_taggable_on_steroids documentation ?

Yes I have but I guess I'm just too new to easily know how to implement it all :slight_smile:

Advice?

Thanks, Elle

> First off, you're probably asking for trouble by having both installed

Well, when I deleted acts_as_taggable, I got an error of:

Processing ProductController#update (for 127.0.0.1 at 2008-07-15 18:35:50) [POST] Parameters: {"commit"=>"Edit", "tags"=>"LS750", "product"=>{...}, "action"=>"update", "id"=>"1", "controller"=>"product"} [...] NoMethodError (undefined method `tag' for #<Product:0x26064fc>):

> Secondly, have you tried just looking at the examples in the > acts_as_taggable_on_steroids documentation ?

Yes I have but I guess I'm just too new to easily know how to implement it all :slight_smile:

Well accordeing to those docs tag doesn't exists: all those examples show manipulation of tag_list (tag_list.add, tag_list.remove etc...)

Fred

I don't have tag_list method. I haven't used it with the gem. My tag controller has:

def list    @page_title = 'Listing tags'    @tags = Tag.find(:all)    @tag_pages, @tags = paginate :tags, :order => :name, :per_page => 10   end   def show     # tag = params[:id]     @tag = Tag.find(params[:id])     @page_title = "Products tagged with '#{tag}'"     @products = Product.find_tagged_with(:any => tag, :separator => ',')   end

and Tag class has:

has_and_belongs_to_many :products

Any suggestions to how I could fix this?

Thanks, Elle

If you look at acts_as_taggable_with_steroids, it adds that method to your models (when you call acts_as_taggable). I think you're getting confused because you think acts_as_taggable_with_steroids is a drop in replacement for acts_as_taggable which it would appear it isn't. The examples in its documentation look pretty straightforward, I suggest you forget what you know about acts_as_taggable and look at those instead.

Fred

I agree the examples do look straightforward. But as usual, I still have questions: I started the console and did the following:

p = Product.find(:first)

=>#<Product:0x2285ad0 @attributes=...

p.tag_list.add("tagnamehere")

=> ["tagnamehere"]

p

=>#<Product:0x2285ad0 @tag_list=["tagnamehere"], @tags=, ...

Now, I don't understand what is the difference between @tag_list and @tags.

I've also looked at http://taggable.rubyforge.org/ and tried to use: p.tag --> error: NoMethodError: undefined method `tag_model' for Product:Class p.tag_with --> error: NoMethodError: undefined method `tag_with' for #<Product:0x2285ad0> p.tag.add --> ArgumentError: wrong number of arguments (0 for 1)         from (irb):7:in `tag'         from (irb):7

Elle

One more question. When I am still in console, I added a tag to p.tag_list, then when I want to save the product (p.save) I get the following error:

NoMethodError: undefined method `find_or_create_with_like_by_name' for Tag:Class         from ./script/../config/../config/../vendor/rails/activerecord/ lib/active_record/base.rb:1235:in `method_missing'         from ./script/../config/../config/../vendor/plugins/ acts_as_taggable_on_steroids/lib/acts_as_taggable.rb:182:in `save_tags'         from ./script/../config/../config/../vendor/plugins/ acts_as_taggable_on_steroids/lib/acts_as_taggable.rb:181:in `each'         from ./script/../config/../config/../vendor/plugins/ acts_as_taggable_on_steroids/lib/acts_as_taggable.rb:181:in `save_tags'         ...

Would anyone know why I get this error?

Thanks, Elle

I agree the examples do look straightforward. But as usual, I still have questions: I started the console and did the following:

p = Product.find(:first)

=>#<Product:0x2285ad0 @attributes=...

p.tag_list.add("tagnamehere")

=> ["tagnamehere"]

p

=>#<Product:0x2285ad0 @tag_list=["tagnamehere"], @tags=, ...

Now, I don't understand what is the difference between @tag_list and @tags.

internal implemenation details

I've also looked at http://taggable.rubyforge.org/ and tried to use: p.tag --> error: NoMethodError: undefined method `tag_model' for Product:Class p.tag_with --> error: NoMethodError: undefined method `tag_with' for #<Product:0x2285ad0> p.tag.add --> ArgumentError: wrong number of arguments (0 for 1)        from (irb):7:in `tag'        from (irb):7

I think you will definitely confuse things by chopping and changing
between multiple tagging libraries all with slightly different
semantics (and which could easily conflict when used simultaneously)

Fred

One more question. When I am still in console, I added a tag to p.tag_list, then when I want to save the product (p.save) I get the following error:

That implies that you've got your own tag model in app/models which is
taking precedence over the one bundled in the plugin.

Fred

Thanks Fred. That helped. I looked at a couple tutorials and none mentioned having a tag model (or the original plugin). One tutorial that was very helpful was: http://dagobart.wordpress.com/2008/06/19/for-purpose-of-reference-enable-tagging-in-a-rails-model/ Removing my tag model let's me save the product :slight_smile:

When I go to view product, I can see my assigned tag. But I still have questions/problems:

Q1. I've been having problems trying to update a product. My product_controller.rb#update has: @product.tag(params[:tags], :separator => ',', :clear => true)

When I try to update a product I get this error: NoMethodError in ProductController#update undefined method `tag' for #<Product:0x23e6dd4>

Q2. To display the tags and links to show tags I use a helper method in application_helper.rb: def display_tags(product)     product.tags.collect{|tag| link_to tag.name, :controller => '/ tag', :action => 'show', :id => tag.name }.join(", ") if product.tags end

My tag_controller.rb#show is: def show     @tag = Tag.find(params[:id])     @page_title = "Products tagged with '#{tag}'"     @products = Product.find_tagged_with(:any => tag, :separator => ',')   end

But when I try to view all other products with the same tag I get an error: NameError in TagController#show undefined local variable or method `tag' for #<TagController: 0x2514c4c>

Should I even have a tag controller? The plugin docs use Product.find_tagged_with('tag'). How could I use that?

Thanks again so much, Elle

Thanks Fred. That helped. I looked at a couple tutorials and none mentioned having a tag model (or the original plugin). One tutorial that was very helpful was: http://dagobart.wordpress.com/2008/06/19/for-purpose-of-reference-enable-tagging-in-a-rails-model/ Removing my tag model let's me save the product :slight_smile:

When I go to view product, I can see my assigned tag. But I still have questions/problems:

Q1. I've been having problems trying to update a product. My product_controller.rb#update has: @product.tag(params[:tags], :separator => ',', :clear => true)

When I try to update a product I get this error: NoMethodError in ProductController#update undefined method `tag' for #<Product:0x23e6dd4>

according to the plugin docs you should be using tag_list (ie
tag_list=, tag_list.add etc...

Q2. To display the tags and links to show tags I use a helper method in application_helper.rb: def display_tags(product)    product.tags.collect{|tag| link_to tag.name, :controller => '/ tag', :action => 'show', :id => tag.name }.join(", ") if product.tags end

My tag_controller.rb#show is: def show    @tag = Tag.find(params[:id])    @page_title = "Products tagged with '#{tag}'"    @products = Product.find_tagged_with(:any => tag, :separator => ',') end

But when I try to view all other products with the same tag I get an error:

You've just got a syntax error there - it should be @tag not tag

NameError in TagController#show undefined local variable or method `tag' for #<TagController: 0x2514c4c>

Should I even have a tag controller? The plugin docs use Product.find_tagged_with('tag'). How could I use that?

Product.find_tagged_with @tag should work (assuming @tag contains a tag)

I'd encourage you to look closely at the docs, all i've done here is
repeat them to you

Fred

Sorry to be a bother and thank you so much for your help Fred. Almost all is fixed. Got one last problem/question.

On every product page, there is a section for recommended products -- which really are products tagged with similar tags. In my catalog_controller.rb#show I have:     @tag = Tag.find(params[:id])     @tagged_related = Product.find_tagged_with (@tag, :match_all => true)

But instead of picking on the tag's id, it gets the product's id. This causes two problems: 1. It doesn't really show related products 2. If the id it gets doesn't exists in the tags table, i get an error. I'm just not sure how to pick up the tag id instead.

Thanks, Elle

If problem is that params[:id] is a product id then surely the problem is just with whatever bit of code produces the link to this page?

Fred