# Plugin Module Help

**URL:** <https://www.ruby-forum.com/t/plugin-module-help/158313>\
**Category:** Rails\
**Created:** [January 21, 2009, 11:46pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313 "2009-01-21T23:46:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 21, 2009, 11:46pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/1 "2009-01-21T23:46:53Z")

</div>

First off, I’m an intermediate Rails developer who is still learning the  
inner workings of Rails… so here is my situation/problem:

I have written a Plugin that accesses a third party API. Within the  
Plugin I had multiple classes that inherit from one another. Example:

* * *

Old Code (Plugin Classes)

* * *

class ApiConn  
attr\_accessor :api\_url, :api\_key

def initialize(url, key)  
@api\_url = url  
@api\_key = key  
end

def api\_perform(class\_type, method, _args)  
begin  
server = XMLRPC::Client.new3({‘host’ =\> self.api\_url, ‘path’ =\>  
“/api/xmlrpc”, ‘port’ =\> 443, ‘use\_ssl’ =\> true})  
result = server.call("#{class\_type}.#{method}", self.api\_key,  
 args)  
rescue XMLRPC::FaultException =\> e  
puts "_\* Api Error: #{e.faultCode} - #{e.faultString} \*\*\*"  
end

return result  
end  
end

class ContactService \< ApiConn  
def api\_contact\_add(data)  
api\_perform(‘ContactService’, ‘add’, data)  
end  
end

…

* * *

Then within my ApplicationController I have this:

* * *

Account  
def current\_account  
@current\_account ||=  
Rails.cache.fetch(“ch:current:account:#{current\_subdomain}”){  
Account.find\_by\_subdomain(current\_subdomain)  
}  
end

def app\_contact\_svc  
@app\_contact\_svc ||=  
ContactService.new("#{current\_account.api\_url}.application.com",  
current\_account.api\_key)  
end

* * *

Well, this has worked fine. However, as I’ve been going through my  
controllers, I’ve noticed that a lot of these calls should be moved to  
the models. For example, I have an ActiveRecord model named Contact and  
I would like to be able to call api\_contact\_add from within the instance  
of that model. I know I would be able to do that by switching the  
plugin to a module.

However, here is the problem: The rails app uses accounts and each  
account has a different api\_url and api\_key. The current\_account(see  
above) is set by the subdomain being used.

So I guess my question is how I can have module attributes set  
specifically for each account through multiple models?

So instead of doing Contact.new(api\_url, key) in an initialize statement  
for each class that includes the ApiConn module, I would like these  
values set once for all models specific to the account.

I hope this make sense 🙂

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 22, 2009, 6:02pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/2 "2009-01-22T18:02:47Z")

</div>

Any help would be appreciated.

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 26, 2009, 3:54pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/3 "2009-01-26T15:54:08Z")

</div>

Nate L. wrote:

> class ApiConn  
> “/api/xmlrpc”, ‘port’ =\> 443, ‘use\_ssl’ =\> true})  
> class ContactService \< ApiConn
> 
> ContactService.new(“#{current\_account.api\_url}.application.com”,  
> I would like to be able to call api\_contact\_add from within the instance  
> So instead of doing Contact.new(api\_url, key) in an initialize statement  
> for each class that includes the ApiConn module, I would like these  
> values set once for all models specific to the account.
> 
> I hope this make sense 🙂

Perhaps something like:

module ContactService  
def self.set\_account(url, key)  
Thread.current[:api\_conn] = ApiConn.new(url, key)  
end

def api\_contact\_add(data)  
Thread.current[:api\_conn].api\_perform(‘ContactService’, ‘add’,  
data)  
end  
end

before\_filter do  
ContactService.set\_account(  
“#{current\_account.api\_url}.application.com”,  
current\_account.api\_key)  
end

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 28, 2009, 3:32am UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/4 "2009-01-28T03:32:17Z")

</div>

Nate L. wrote:

> Is that multi-thread safe for the newer versions of rails?

Yes.

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 28, 2009, 8:59pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/5 "2009-01-28T20:59:29Z")

</div>

Mark Reginald J. wrote:

> Nate L. wrote:
> 
> > Is that multi-thread safe for the newer versions of rails?
> 
> Yes.
> 
> –  
> Rails Wheels - Find Plugins, List & Sell Plugins -  
> [http://railswheels.com](http://railswheels.com)

Ok thanks. I guess my next question is more in regards to threads, but  
if I have multiple accounts logged in how do the threads stay specific  
for each account?

Looks like I need to read up on threads.

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 28, 2009, 9:33pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/6 "2009-01-28T21:33:26Z")

</div>

Mark Reginald J. wrote:

> Yes.

Is the thread specific for the request in rails? Meaning… the  
before\_filter will be run on each rails action/request therefore is a  
new thread created in rails for that process? Jeez… I hope I’m  
explaining it properly 🙂

Also, since that before filter is creating a new AppConn obj do I have  
to worry about performance? It just seems that creating a new AppConn  
for each rails request seems like overkill. Am I wrong in thinking  
that?

Thanks again for your responses.

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 26, 2009, 9:58pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/7 "2009-01-26T21:58:05Z")

</div>

Mark Reginald J. wrote:

> Perhaps something like:
> 
> module ContactService  
> def self.set\_account(url, key)  
> Thread.current[:api\_conn] = ApiConn.new(url, key)  
> end
> 
> def api\_contact\_add(data)  
> Thread.current[:api\_conn].api\_perform(‘ContactService’, ‘add’,  
> data)  
> end  
> end
> 
> before\_filter do  
> ContactService.set\_account(  
> “#{current\_account.api\_url}.application.com”,  
> current\_account.api\_key)  
> end
> 
> –  
> Rails Wheels - Find Plugins, List & Sell Plugins -  
> [http://railswheels.com](http://railswheels.com)

Hey Mark,

Thanks for the response. I think I’m following what you’re suggesting.  
Is that multi-thread safe for the newer versions of rails?

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 29, 2009, 4:48pm UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/8 "2009-01-29T16:48:48Z")

</div>

Thanks Mark!

---

<div class="post-metadata">

**Author:** ![nateleavitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3bc359/32.png) [@nateleavitt](https://www.ruby-forum.com/u/nateleavitt)\
**Post date:** [January 29, 2009, 4:35am UTC](https://www.ruby-forum.com/t/plugin-module-help/158313/9 "2009-01-29T04:35:51Z")

</div>

Nate L. wrote:

> Is the thread specific for the request in rails? Meaning… the  
> before\_filter will be run on each rails action/request therefore is a  
> new thread created in rails for that process? Jeez… I hope I’m  
> explaining it properly 🙂

Yes, each thread only carries one request at time.

> Also, since that before filter is creating a new AppConn obj do I have  
> to worry about performance? It just seems that creating a new AppConn  
> for each rails request seems like overkill. Am I wrong in thinking  
> that?

Creating such a small AppConn object with each request shouldn’t  
be a problem.

If it is you can instead do

```
def self.set_account(url, key)
  if ac = Thread.current[:api_conn]
    ac.url, ac.key = url, key
  else
    Thread.current[:api_conn] = ApiConn.new(url, key)
  end
end

```

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)
