ruby-on-railsapirestactiveresource

ActiveResource how to fetch a resource from a REST API that has a singular name?


I am trying to grab data from a third-party library that has an API that looks like:

https://foo.com/user.json?username=<USERNAME>

I can't figure out how to force ActiveResource to use "user.json" instead of "users.json". Is it possible?

I got it working with the reactive_resources gem ... is there a way to do it in just pure ActiveResources?


Solution

  • class User < ActiveResource::Base
      self.element_name = "user"
    end
    

    Next, you are going to ask how to get one element from the URL which looks to ActiveResource to be //foo.com/user.json instead of //foo.com/user/.json

    User.find(:one, :from => "https://foo.com/user.json?username=#{<USERNAME>}"
    

    Edit in response to comment

    Is there a way to do this without having to enter the full URL of the request every single time I want to use find()?

    One way is to define a method in the class to do the full URL for you.

    class User < ActiveResource::Base
      self.element_name = "user"
    
      def self.find_by_username(username)
        find(:one, :from => "https://foo.com/user.json?username=#{username}"
      end
    
      def find
        self.class.find(:one, :from => "https://foo.com/user.json?username=#{username}"
      end
    end
    

    Another way is to redefine element_path.

    class User < ActiveResource::Base
      self.element_name = "user"
    
      def self.element_path(id, prefix_options = {}, options = {})
        "https://foo.com/user.json?username=#{prefix_options["user_id"]}"
      end
    end
    

    Some would call this monkey-patching, others would call it Object Oriented Programming. I say it's only monkey-patching when you are going into the code or using Ruby's dynamic nature to change the base behavior and this is a totally legitimate way to do things in Object Oriented Programming. However, the Ruby community doesn't use OOP much, pretty much ignoring inheritance in favor of much looser (and less well behaved) mix-ins, and only using duck-typing for polymorphism.

    The issues with having to mess with ActiveResource to build an URL where you cannot redefine the web service to accept the ActiveResource conventions is why many are using HTTParty instead. "If you have to build the URL, might as well use HTTParty."