I’m needing some help here … I want to do an extension on a
has_and_belongs_to_many to build a custom add method to the
association.
i have a table locations that has a many-to-many association with a
tags tabel using a locations_tags table.
i want to add a method to the Location has_and_belongs_to_many
association so that i can do something like this on the location
model:
myLocation.tags.add_by_names ‘tag1 tag2 tag3’
On the extension i want to do something like this:
class Location < ActiveRecord::Base
has_and_belongs_to_many :tags do
def add_by_names tag_names
tag_names.split(" ").each do |tag_name|
tag = Tag.find_by_name(tag_name) || Tag.create(:name =>
tag_name)
tags << tag unless tags.find(tag.id)
end
end
end
The problem is, that i cant feager out how to have access to location
tags collection inside my custom create method.
I’ve been playing around with association extensions lately, and you
should know they aren’t 100% stable yet. But they do work pretty well
for most stuff.
Something that isn’t obvious is that the context for code in the
extension is the association itself. That means that a message on self
will be sent to the association object, in your example,
myLocation.tags.
Here’s how I would write what you’re attempting:
class Location < ActiveRecord::Base
has_and_belongs_to_many :tags do
def add_by_names(tag_names)
tag_names.split(" ").each { |name| find_or_create_by_name(name) }
end
end
That’s untested but I think it should work ok. Note that I used the
dynamic finder find_or_create_by_name, which is pretty handy for just
what you’re doing.
–josh
Pedro C. wrote:
Hi to all,
I’m needing some help here … I want to do an extension on a
has_and_belongs_to_many to build a custom add method to the
association.
i have a table locations that has a many-to-many association with a
tags tabel using a locations_tags table.
i want to add a method to the Location has_and_belongs_to_many
association so that i can do something like this on the location
model:
myLocation.tags.add_by_names ‘tag1 tag2 tag3’
On the extension i want to do something like this:
class Location < ActiveRecord::Base
has_and_belongs_to_many :tags do
def add_by_names tag_names
tag_names.split(" ").each do |tag_name|
tag = Tag.find_by_name(tag_name) || Tag.create(:name =>
tag_name)
tags << tag unless tags.find(tag.id)
end
end
end
The problem is, that i cant feager out how to have access to location
tags collection inside my custom create method.
Oh cool, nice work. I didn’t know that part of the incantation. That
looks so pretty. I’m really starting to like association extensions a
lot.
–josh
Pedro C. wrote:
Got it to work. Just a litle more magic required (added self << find
… )
class Location < ActiveRecord::Base
has_and_belongs_to_many :tags do
def add_by_names(tag_names)
self << tag_names.split(" ").each { |name| find_or_create_by_name(name) }
end
end
Got it to work. Just a litle more magic required (added self << find
… )
class Location < ActiveRecord::Base
has_and_belongs_to_many :tags do
def add_by_names(tag_names)
self << tag_names.split(" ").each { |name|
find_or_create_by_name(name) }
end
end
thanks a lot for you help.
Pedro.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.