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 :) -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Any help would be appreciated. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Nate Leavitt wrote:> 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 :)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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mark Reginald James 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.comHey 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? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Nate Leavitt wrote:> Is that multi-thread safe for the newer versions of rails?Yes. -- Rails Wheels - Find Plugins, List & Sell Plugins - http://railswheels.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mark Reginald James wrote:> Nate Leavitt wrote: > >> Is that multi-thread safe for the newer versions of rails? > > Yes. > > -- > Rails Wheels - Find Plugins, List & Sell Plugins - > http://railswheels.comOk 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. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mark Reginald James 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. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Nate Leavitt 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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks Mark! On Jan 28, 8:34 pm, Mark Reginald James <m...-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> Nate Leavitt 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--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---