Question

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?

Was it helpful?

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."

OTHER TIPS

If you only need to get rid of resource name pluralization in the URL, override collection_name:

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

  def self.collection_name
    element_name
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top