Announcing:

LessConf 2012 will be Feb 23-24 in Atlanta, Georgia!
Register today and make us smile super big!

Custom Parameters in ActiveResource#create

written by Steven on October 30, 2008

I recently created a public API for Less Accounting. In addition to requiring the username a password for the user that is logging in, the API also requires a application specific api_key to be provided for each request. This allows me to track every api call and turn off malicious applications. This works great, every request adds the query string parameter "api_key" with the value of their key and Bob's your uncle. Except if you happen to be writing a rails app and want to create a model using ActiveResource. Then you're screwed. This is because the create method in AR doesn't allow you to pass in extra parameters. It takes a hash of attributes and then wraps the hash in a {:model=>attributes} and that is all. So if you add a parameter, like :api_key, then it will be delivered as model[api_key]=key in the params hash. Not nice. And it's even worse because there has been a patch out there which address this problem. (I just nudged the core team, so hopefully this patch will finally be applied). But in the mean time I wrote a nice little hack:

class ActiveResource::Base

  def self.custom_method_collection_url(method_name, options = {})
    prefix_options, query_options = split_options(options)
    if method_name == :create
      "#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
    else
      "#{prefix(prefix_options)}#{collection_name}/#{method_name}.#{format.extension}#{query_string(query_options)}"
    end
  end
end

And then you can call create using the post method:

post(:create, {:expense=>{:title => expense.title,
        :notes => expense.note
        :amount => expense.amount
      }, :api_key=>'68e050b6-e879-4f78-adf3-d898387036fc'})

I admit it is not the cleanest solution, and you would have to do something similar for update, but at least it's done.

Note: Lourens had an idea to concat the password with the api_key like this: "#{password}|{#api_key}" and split it on the server. That is also a nice solution. So take your pick.

I hope you'll join us for LessConf 2012, Feb 23-24, 2012 in Atlanta Ga.
We're releasing our first ebook titled "How we built our consultancy to over $1,000,000 a year in revenue." Get early access to the ebook.

Leave a Comment

About Steven
Steven Bristol has written code for the past 20 years. He like green vegetables and kittens, oh and butterflies too. He loves to throw ninja stars at his enemies.

You Should...

Follow Steven on Twitter
Friend Steven on Facebook
Subscribe
LessEverything Copyright 2011 LessEverything.com
We don't like footers, they're kinda boring