# Help On Associations Extension

**URL:** <https://www.ruby-forum.com/t/help-on-associations-extension/54219>\
**Category:** Rails\
**Created:** [February 26, 2006, 7:06pm UTC](https://www.ruby-forum.com/t/help-on-associations-extension/54219 "2006-02-26T19:06:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jotape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c77e96/32.png) [@jotape](https://www.ruby-forum.com/u/jotape)\
**Post date:** [February 26, 2006, 7:06pm UTC](https://www.ruby-forum.com/t/help-on-associations-extension/54219/1 "2006-02-26T19:06:44Z")

</div>

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.

Is there a way to do this?

any help or point to some examples welcome.

thanks.  
Pedro.

---

<div class="post-metadata">

**Author:** ![jotape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c77e96/32.png) [@jotape](https://www.ruby-forum.com/u/jotape)\
**Post date:** [February 26, 2006, 7:34pm UTC](https://www.ruby-forum.com/t/help-on-associations-extension/54219/2 "2006-02-26T19:34:41Z")

</div>

Hi Pedro,

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.
> 
> Is there a way to do this?
> 
> any help or point to some examples welcome.
> 
> thanks.  
> Pedro.

---

<div class="post-metadata">

**Author:** ![jotape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c77e96/32.png) [@jotape](https://www.ruby-forum.com/u/jotape)\
**Post date:** [February 27, 2006, 12:19am UTC](https://www.ruby-forum.com/t/help-on-associations-extension/54219/3 "2006-02-27T00:19:15Z")

</div>

Hi Josh,

I tried the code you sent, but its only saving the tag records and not  
the association itself (the locations\_tags record)…

The myLocations.tags does not contain the new tags after calling:

myLocation.tags.add\_by\_names

Any sugestions?

thanks.  
Pedro.

---

<div class="post-metadata">

**Author:** ![jotape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c77e96/32.png) [@jotape](https://www.ruby-forum.com/u/jotape)\
**Post date:** [February 27, 2006, 1:36am UTC](https://www.ruby-forum.com/t/help-on-associations-extension/54219/4 "2006-02-27T01:36:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jotape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c77e96/32.png) [@jotape](https://www.ruby-forum.com/u/jotape)\
**Post date:** [February 27, 2006, 10:56am UTC](https://www.ruby-forum.com/t/help-on-associations-extension/54219/5 "2006-02-27T10:56:44Z")

</div>

couldn’t agree more. really beautiful stuff …

---

<div class="post-metadata">

**Author:** ![jotape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c77e96/32.png) [@jotape](https://www.ruby-forum.com/u/jotape)\
**Post date:** [February 27, 2006, 12:40am UTC](https://www.ruby-forum.com/t/help-on-associations-extension/54219/6 "2006-02-27T00:40:26Z")

</div>

Hi,

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.
