0

I have a location field on my User model with two possible values, Spain and France (maybe more in the future). I need to make API calls for each user but call a different API depending on the user's location (also, parse the response differently). I have no idea what the best way to solve this is.

Here's more or less what my code looks like now:

class Api::Foobar
  include HTTParty
  base_uri 'http://demo.foobar.es/vweb/xml'

  GLOBAL_OPTIONS = {edad: 'anciano', farmacovigilancia: false, deportista: false, administrativas: false}

  def initialize(user)
    @user = user
  end

  def contraindications
    self.class.get("/ws_patient/alertas", query: GLOBAL_OPTIONS.merge(user_options) )
  end

  def self.medications_by_name(name)
    response = get("/ws_drug/SearchByName", query: {value: name} )
    response['object']['drug_set']['drug']
  end

  .....

end

I'm doing things like Api::Foobar.medications_by_name('asp') or Api::Foobar.new(User.first).contraindications

I'd like to build an abstraction layer that allows me to call the same methods for each user and automatically pick the appropriate class/module/api based on the users location. Can anyone point me in the right direction? Maybe something on best practices when building abstraction layers like this?

========== Edit ==========

I ended up namespacing the classes one more level and adding this method to the User class:

  def foobar_api
    if !self.location.nil?
      Object.qualified_const_get("Api::Foobar::#{self.location.capitalize}").new(self)
    else
      Api::Foobar::Spain.new(self)
    end
  end

now I'm calling User.first.foobar_api.contraindications

Can anybody comment if this is a good idea? or if there is a better way

joshblour
  • 1,024
  • 10
  • 19

1 Answers1

0

Have a perform method in the class which accepts the user object. And based on the user-location value, you could use one amongst the internal methods.

Satya Kalluri
  • 5,148
  • 4
  • 28
  • 37
  • I've seen `perform` and `run` methods but never written one. What does it do? How would I search to read more about it? – joshblour Nov 25 '13 at 10:30
  • It doesn't necessarily have to be a PERFORM method. You could use something like in this GIST (https://gist.github.com/satyatechsavy/7639411). I am assuming that the medications_by_name method takes the country-name as parameter – Satya Kalluri Nov 25 '13 at 10:34
  • Oh, I understand. The location is stored on the user record. There are about 10-15 more methods inside this API class that I omitted. I'd like to be able to do something like this `Api::Foobar.new(User.first).contraindications` and then depending on the user's country, it will call the `contraindications` method (or any of the other methods) from inside the `Api::Foobar::Spain` or `Api::Foobar::France` classes. – joshblour Nov 25 '13 at 10:47