240

Could anyone explain params in Rails controller: where they come from, and what they are referencing?

  def create
    @vote = Vote.new(params[:vote])
    item = params[:vote][:item_id]
    uid = params[:vote][:user_id]
    @extant = Vote.find(:last, :conditions => ["item_id = ? AND user_id = ?", item, uid])
    last_vote_time = @extant.created_at unless @extant.blank?
    curr_time = Time.now
  end

I would like to be able to read this code line-by-line and understand what's going on.

tereško
  • 58,060
  • 25
  • 98
  • 150
Dru
  • 9,632
  • 13
  • 49
  • 68
  • 2
    What's your background on server side web development? What technologies do you already know? – Maurício Linhares Jul 30 '11 at 21:21
  • 3
    I've been with HTML and CSS for years. Taken classes which used PHP, JS, and Java. Used very little MVC with php though. I really learned programming using Java. And I thoroughly understand database theory. – Dru Jul 30 '11 at 21:26

5 Answers5

293

The params come from the user's browser when they request the page. For an HTTP GET request, which is the most common, the params are encoded in the URL. For example, if a user's browser requested

http://www.example.com/?foo=1&boo=octopus

then params[:foo] would be "1" and params[:boo] would be "octopus".

In HTTP/HTML, the params are really just a series of key-value pairs where the key and the value are strings, but Ruby on Rails has a special syntax for making the params be a hash with hashes inside. For example, if the user's browser requested

http://www.example.com/?vote[item_id]=1&vote[user_id]=2

then params[:vote] would be a hash, params[:vote][:item_id] would be "1" and params[:vote][:user_id] would be "2".

The Ruby on Rails params are the equivalent of the $_REQUEST array in PHP.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • 13
    Equivalent to $_REQUEST except that $_REQUEST includes get, post and cookie data, while params only get and post data. – Parziphal Mar 18 '13 at 04:15
  • 3
    @renocor POST data is included in the Rails `params` hash as well. Cookie data is included in the `session` hash. – Richard Jones Nov 26 '13 at 19:44
  • This answer leaves out one other source of params: the URL. See hammar's answer for more information. – Richard Jones Nov 26 '13 at 19:46
  • 1
    toasterlovin, it sounds like you did not read the second sentence of my answer or look at the first example. – David Grayson Nov 27 '13 at 00:21
  • can values in param even be a number or is it always a string? – Ankit Dhingra Apr 21 '14 at 11:30
  • 1
    @AnkitDhingra...I think it will always be string as HTTP params are really only key/value pair and Rails (most probably Rack gem) parses that into hashes and arrays according to key value, but I have not seen anything of the sort which tells Rails that the value is a number. – rubyprince Jun 10 '14 at 06:44
  • What would be the value of `params[:foo]` if url could be like: http://www.example.com/?foo=1&boo=octopus&foo=2 – Shameer Kashif Jul 19 '18 at 09:51
79

As others have pointed out, params values can come from the query string of a GET request, or the form data of a POST request, but there's also a third place they can come from: The path of the URL.

As you might know, Rails uses something called routes to direct requests to their corresponding controller actions. These routes may contain segments that are extracted from the URL and put into params. For example, if you have a route like this:

match 'products/:id', ...

Then a request to a URL like http://example.com/products/42 will set params[:id] to 42.

hammar
  • 138,522
  • 17
  • 304
  • 385
51

Params contains the following three groups of parameters:

  1. User supplied parameters
  • GET (http://example.com/url?param1=value1&param2=value2 will set params[:param1] and params[:param2])
  • POST (e.g. JSON, XML will automatically be parsed and stored in params)
  • Note: By default, Rails duplicates the user supplied parameters and stores them in params[:user] if in UsersController, can be changed with wrap_parameters setting
  1. Routing parameters
  • match '/user/:id' in routes.rb will set params[:id]
  1. Default parameters
  • params[:controller] and params[:action] is always available and contains the current controller and action
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
thejaz
  • 2,763
  • 2
  • 26
  • 40
  • 1
    Could you expand your Note under `User supplied parameters` a little more? For instance, an example of the params hash in the UsersController would be helpful. Your example makes it sound like the hash will look something like: `{first_name: "mike", user: {first_name: "mike"} ...}` Is that correct? – 7stud Jul 29 '13 at 07:48
  • 1
    I'm not seeing that in rails4. For instance, `{"_method"=>"put", "authenticity_token"=>"gubHya6uQrQLjPRXhOC0RUuCRdn7NFr6CeKrbRfBSHI=", "ripe"=>"true", "action"=>"update", "controller"=>"apples", "id"=>"4"}`. Forgive me if I'm wrong, I'm a rails beginner. According to your note, I should see: `{"_method"=>"put", "authenticity_token"=>"gubHya6uQrQLjPRXhOC0RUuCRdn7NFr6CeKrbRfBSHI=", "ripe"=>"true", "apple" => {"ripe"=>"true"}, "action"=>"update", "controller"=>"apples", "id"=>"4"}` I don't know if that has to do with _strong parameters_ in rails4 or not. – 7stud Jul 31 '13 at 09:45
  • 2
    I am seeing the duplicated params in Rails 4, but only under json POST requests (using Angularjs) not under Rails own HTML posts. This link explains why: http://stackoverflow.com/questions/10774972/rails-wrap-parameters-vs-include-root-in-json-what-is-the-difference – Homan Sep 07 '13 at 05:05
13

Basically, parameters are user specified data to rails application.

When you post a form, you do it generally with POST request as opposed to GET request. You can think normal rails requests as GET requests, when you browse the site, if it helps.

When you submit a form, the control is thrown back to the application. How do you get the values you have submitted to the form? params is how.

About your code. @vote = Vote.new params[:vote] creates new Vote to database using data of params[:vote]. Given your form user submitted was named under name :vote, all data of it is in this :vote field of the hash.

Next two lines are used to get item and uid user has submitted to the form.

@extant = Vote.find(:last, :conditions => ["item_id = ? AND user_id = ?", item, uid])

finds newest, or last inserted, vote from database with conditions item_id = item and user_id = uid.

Next lines takes last vote time and current time.

Smar
  • 8,109
  • 3
  • 36
  • 48
9

On the Rails side, params is a method that returns an ActionController::Parameters object. See https://stackoverflow.com/a/44070358/5462485

Margotte
  • 101
  • 1
  • 5
  • 5
    +1 for clarifying that `params` is a method. Ruby can make it difficult to distinguish variables from methods – samrap Jul 06 '18 at 00:01