Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you handle RESTful URL parameters in a Ruby on Rails application?

I am dealing with a very simple RESTful Rails application. There is a User model and I need to update it. Rails coders like to do:

if @user.update_attributes(params[:user])
...

And from what I understand about REST, this URL request should work:

curl -d "first_name=tony&last_name=something2&v=1.0&_method=put" http://localhost:3000/users/1.xml

However, it's quite obvious that will not work because each URL parameter will be parsed to the variable "params" and not "params[:user]"

I have a hackish fix for now, but I wanted to know how people usually handle this.

Thanks

like image 494
Tony Avatar asked Dec 11 '25 06:12

Tony


2 Answers

It's just a matter of how Rails parses parameters. You can nest parameters in a hash using square brackets. Something like this should work:

curl -d "user[first_name]=tony&user[last_name]=something2&v=1.0&_method=put" http://localhost:3000/users/1.xml

This should turn into

{:user=>{:last_name=>"something", :first_name=>"tony"}}

in your params hash. This is how Rails form helpers build the params hash as well, they use the square brackets in the form input tag name attribute.

like image 63
chrisdinn Avatar answered Dec 12 '25 20:12

chrisdinn


It's a tradeoff; You can have slightly ugly urls, but very simple controller/models. Or you can have nice urls but slightly ugly controller/models (for making custom parsing of parameters).

For example, you could add this method on your User model:

class User < ActiveRecord::Base

  #class method
  def self.new_from_params(params)
    [:action, :method, :controller].each{|m| params.delete(m)}
    # you might need to do more stuff nere - like removing additional params, etc
    return new(params)
  end
end

Now on your controller you can do this:

class UsersController < ApplicationController
  def create
    #handles nice and ugly urls
    if(params[:user]) @user=User.new(params[:user])
    else @user = User.new_from_params(params)
    end

    if(@user.valid?)
    ... etc
    end
  end
end

This will handle your post nicely, and also posts coming from forms.

I usually have this kind of behaviour when I need my clients to "copy and paste" urls around (i.e. on searches that they can send via email).

like image 37
kikito Avatar answered Dec 12 '25 20:12

kikito