Rails Parameters

A Beginner's Guide to Rails Parameters

Parameters in Rails let you access data sent by the browser, either in the URL or via form submission. In this article, we'll cover the basics of parameters, including what they are, how they work, and why they're important. We'll also learn how you can pass parameters when redirecting a request.

6 min read

If you are building a dynamic web application, you will need to access the user-submitted data on the server. Maybe the user uploaded a photo, wrote a comment, posted a tweet, or clicked a link containing the id of an article they want to read.

How do you access this data on the server, in your Rails application?

That’s where parameters enter the picture.

Similar to the parameters to a function, Rails parameters read the data submitted by the user's browser, either in the link or via form submission and make it available in your Rails application.

Consider the following code that mimics the browser-server interaction.

# Rails app
def rails(params)
  # do stuff with params
end

# browser sends the parameters to Rails app
rails(id: 5, name: 'learn-to-program')

The rails function represents your application. The browser sends a request to the app by calling this function, passing some data. The Rails app makes this data available in the params object.

Hope that gave you an intuitive understanding of the concept of parameters.

There are two ways in which the browser can send data to the Rails application: Query Strings and Form Submissions.

Query Strings

  • Include the data in the URL after the ?, e.g. /posts?id=3&user=ak
  • Data consists of key-value pairs separated by &
  • Typically submitted in a GET request, e.g. clicking a link

Form Submission

  • Contains the data entered into a form by the user.
  • Typically posted in a POST request, e.g. submitting a form

The important thing to know is that Rails doesn’t care about the request type (GET or POST) when accessing the data on the server.

Rails won’t distinguish between the information it receives from query strings and the data from a form submission. It groups all the data into the params hash, which is available in the controller.

Let's inspect both approaches in detail.

Query Strings

Let's assume you've got this route: get 'posts/sample'.

When you visit the URL http://localhost:3000/posts/sample?id=3&user=ak, Rails makes the query data available in the following params hash:

{
  "id"         => "3", 
  "user"       => "ak", 
  "controller" => "posts", 
  "action"     => "sample"
}

Note that the params hash also includes the controller and action names. Though you can access it in your controller, Rails recommends using the controller_name and action_name methods to access these values.

The params object is in fact, an instance of ActionController::Parameters class, that acts like a hash. We can assume it’s a hash for all practical purposes.

#<ActionController::Parameters {"id"=>"3", "user"=>"ak", "controller"=>"posts", "action"=>"sample"} permitted: false>

The permitted property is related to strong parameters. To learn more about them, check out the following article:

Why You Need Strong Parameters in Rails
In this post, I will explain the Mass Assignment vulnerability and how you can use the Rails strong parameters API to address it.

Form Submission

Consider this form which makes a POST request on the /posts/upload endpoint.

<form action="posts/upload" method="post">
  <div>
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name">
  </div><br>

  <div>
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_email">
  </div><br>

  <button type="submit">Submit</button>
</form>

When you fill out and submit the form, the browser sends the data to your Rails application, which creates the following params hash:

{
  "user_name"  => "Akshay", 
  "user_email" => "ak@email.com", 
  "controller" => "posts", 
  "action"     => "build"
}

Notice that the keys I am using on the params hash are the same values I used for the name attributes on the form. Rails extracts these values from the submitted data and adds them to the params hash.

Nested Parameters

Instead of sending the name values as keys directly, you can group them under a common key. For example, to group the user_name and user_email under the client key, change the name attribute's value as follows:

<form action="upload" method="post">
  <div>
    <label for="name">Name:</label>
    <input type="text" id="name" name="client[user_name]">
  </div><br>

  <div>
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="client[user_email]">
  </div><br>

  <button type="submit">Submit</button>
</form>

This will create the following params hash on the server:

{
  "client": {
    "user_name":"Akshay",
    "user_email":"ak@email.com"
  },
  "controller": "posts",
  "action":"build"
}

Notice that Rails has grouped the user_name and user_email under the client.

Sending JSON

For a rails API, you can send JSON data from the client. Rails will load it into the params hash, and you can access it in the controllers.

For example, if you send the following JSON data:

{ "company": { "name": "acme", "address": "123 Carrot Street" } }

The params hash will be

{ :company => { "name" => "acme", "address" => "123 Carrot Street" } }

Dynamic Parameters

If your route URL contains a symbol, Rails will use that symbol name as the key in the params hash.

The following route instructs Rails to map the URL parameter to title.

# routes.rb
get 'posts/lookup/:title', to: 'posts#lookup'

If you visit the posts/lookup/learn-to-code URL, Rails will extract the foo string and assign it to the title key on the params hash.

{
  "controller" => "posts", 
  "action" => "lookup", 
  "title" => "learn-to-code"
} 

To learn more about the Rails router, check out the following article:

Understanding the Rails Router: Why, What, and How
The router is the entry point of your Rails application. It acts as the gatekeeper for all incoming HTTP requests, inspecting and sending them to a controller action; even filtering and rejecting them if necessary. In this article, we’ll do a deep dive into the Rails Router to understand it better.

How to Pass Parameters when Redirecting

When redirecting to another route, you can pass the parameters by passing them as hash parameters to the redirect_to method. For example,

redirect_to controller: 'articles', action: 'show', id: 3, user: 'ak'

The ArticlesController can access the passed values using the params hash as usual. Also remember that you can’t redirect a POST request.

What about Strong Parameters?

Now, you might be wondering why I haven't talked about strong parameters at all in this article. The reason being, strong parameters is an important topic and I've written a separate post that explains them in-depth. Check it out:

Why You Need Strong Parameters in Rails
In this post, I will explain the Mass Assignment vulnerability and how you can use the Rails strong parameters API to address it.

I will revise and polish this post to republish it soon. So stay tuned.

That said, I hope that you have a pretty good understanding of how parameters work in Rails by now. To summarize what we’ve learned so far:

  • All the data sent by the browser is available in the params hash.
  • Rails won't differentiate between the data that comes from a GET request (query string parameters) vs. the data that comes from a POST request (form submission).
  • You can pass nested data using special syntax in your forms and Rails will make it available as a nested Hash.

That's a wrap. I hope you liked this article and you learned something new.

As always, if you have any questions or feedback, didn't understand something, or found a mistake, please leave a comment below or send me an email. I look forward to hearing from you.

If you'd like to receive future articles directly in your email, please subscribe to my blog. If you're already a subscriber, thank you.