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, and you want to read this data to do something useful.
How do you access this data on the server, in your Rails application?
Answer: Rails parameters let you access the user-submitted data in your Rails application, specifically in your Rails controllers.
params
hash.Consider the following code that mimics the browser-server interaction.
# Rails app
def rails(params)
id = params[:id]
name = params[:name]
end
# browser sends the parameters to Rails app
rails(id: 5, name: 'learn-to-program')
The rails
function represents your Ruby on Rails application. The browser sends a request to the app by calling this function, passing some data. The Rails app makes this data available in a Hash-like object, which is called, not surprisingly, params, which stands for parameters.
Hope that gave you an conceptual understanding of parameters in Rails.
There are two ways in which the browser can send data to the Rails application: via query strings in the URL and by submitting a form.
Query Strings
- Include the data in the URL after the
?
, e.g./posts?id=3&user=ak
- Multiple pieces of key-value pairs are 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.
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'
which dispatches the request to the posts/sample
URL to the sample
action method on the PostsController
class.
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 them both 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:
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
You can send JSON data from the client to the application. 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" } }
Sending Arrays and Hashes as Parameters
If you're using named route helpers, you can pass arrays as follows:
get dashboard_path(frameworks: [ "Ruby on Rails", "Laravel" ])
params[:frameworks] # [ "Ruby on Rails", "Laravel" ]
Otherwise, you can pass the following URL and Rails will parse it to build the array parameters:
http://www.example.com/?frameworks[]=Ruby+on+Rails&frameworks[]=Laravel
In fact, the above named helper generates the same URL.
Similarly, you can pass a hash as follows:
get home_path(language: { name: "Ruby", creator: "Matz" })
params[:language][:name] # "Ruby"
params[:language][:creator] # "Matz"
The above helper generates the following URL:
http://www.example.com/?language[creator]=Matz&language[name]=Ruby
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 learn-to-code
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:
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:
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 found this article helpful 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 reply to all emails I get from developers, and I look forward to hearing from you.
If you'd like to receive future articles directly in your email, please subscribe to my blog. Your email is respected, never shared, rented, sold or spammed. If you're already a subscriber, thank you.