Wham Bam, Thanks, Params

How “params” is generated, used, and is stronger than a plain hash

Image by Arek Socha from Pixabay

So you’ve gotten started with Ruby and you’re ready to bring your code to life with Rails! You’ve gotten the basics of a Model-View-Controller (MVC) design down, your RESTful routes are set, and the server’s up and running. The index view was a breeze, but now you’re trying to render a view of a single instance of your model and you recall the standard syntax for that route (for a cat, because, why not):

Huh, where’s that coming from and where does it go? This route syntax is indicating to your application that the will dynamically be determined by the value in the URL, which corresponds to the primary key of the instance of from the database you want to see. For example:

would bring up information on a cat with an of 42.

But how does that get passed from the URL to the controller to retrieve the right cat? Nested in the HTTP request is an object, which contains the cat’s id number in a key-value pair. This allows us to find the cat with code like:

photo of a cat, captioned “where did params come from?”
photo of a cat, captioned “where did params come from?”
Plot twist, it’s a database of photos of the same cat. My foster cat.

Where did the params hash come from?

The is a hash-like object which allows users, whether they know it or not, to send information along with requests to the server. (These parameter objects are not quite hashes, but more on that later.) Some of the more common ways will be sent to your controller are through the URL itself, a query parameter, or a form. Let’s go over those briefly.

The URL

As described in the example above, the may contain information from the URL in plain sight, like when it identified the primary key of the object the user wanted to find.

Query parameters

As you travel around the web, take note of any question marks that appear in the URLs (or Uniform Resource Locators) of the pages you are browsing. The “?” delimits the boundary between the resource and the querying string, a key-value pair that is communicated through the .

For example, when you use a search engine, you are sending search terms to run some sort of query. You can see some evidence of this in the results page. If you go to DuckDuckGo and enter “cat photos”, the page you get back will have something like in the URL.

Query parameters are not limited to searching. You may also often see UTM parameters (e.g. ) in your address bar, which can track if a user has reached a site through an e-mail campaign or a different website, or any number of things! Parameters are everywhere, and contain a lot of useful information.

As a quick use example, as the administrator of animal databases, let’s say you branched out from cats and now work with dogs. You entered these dogs into the database as they came (…or used the Faker gem to generate some) and when grabbing a list of them through , they display in primary key order.

But what if a user wanted to sort them alphabetically? You could make a new page called and use a differently ordered list, possibly involving new routes or at the very least, a new view.

Or you could create a link to reload the index page, with parameters, and use some logic in your controller index action to display a different order.

The link in your index view and index action in your dogs controller could look something like this:

Result:

animated demonstration of reloaded index page with dogs in alphabetical order
animated demonstration of reloaded index page with dogs in alphabetical order

Form submissions

Another direct way you may encounter early on is when you implement a form on your web interface. When a user enters information in a “Contact Us” form, their name and any other information they entered are sent to the controller (and probably ultimately written to your database) via . As behave like hashes, information can be infinitely nested and hold quite a lot!

A user wants to add another dog to the database. Let’s take a look at an simple example form and the resulting object. To add a dog, the user must enter the dog’s name and choose the dog’s type, as predetermined by the table.

(If you’re curious, here is the resulting HTML that the Action View form helpers above generated. The form won’t submit anything, but you can look at the HTML and visualize the form better!)

If a user enters a name of “Hamstar”, chooses “smol pupperino”, and hits that submit button, here are the that are returned to the server (the will differ):

Nestled in there are the values you need to create the dog!

You can also play around with / form helpers and buttons (tiny forms), too, to get and pass through the information you seek in your controller methods.

Is params a hash? How do we use params data?

Technically, is not a hash, though it looks like one. As you can see above, is actually an instance of. We can interact with largely like a hash and in fact, up until Rails 5.0, did inherit from the class. As a different class, hashes have some familiar methods that does not, such as , , , and .

But has a few tricks of its own. Here are all the methods available to that a hash can’t do.

There is a lot here having to do with safety and permissions! That’s because are the conduit through which the unsafe internet/absent-minded user can send data to your controllers and possibly ultimately your database. And for best practices, you should use…

Strong Params! 🦾

You should be glad that isn’t exactly a hash because there are two important methods to learn to use on them: and . If you recall a little while ago, the had this little value at the end: . If you tried to use directly as you would with a hash to provide attributes to a new dog, you would have hit an “ActiveModel::ForbiddenAttributesError” (given standard settings). To allow form data to be used, you would have to do something like this:

The method verifies that the contains a key of and information about a dog. If comes in without this key, most likely it’s form data from elsewhere, or data that isn’t useful to you to create or update an instance of theclass. The method specifies which keys within to allow the values of. You could allow a user to change a dog’s name, for example, but not their type.

With these two methods performed on , you can use it directly in creating your dog with and as attributes.

But other than that small feature, treat as you would any other hash!

…one more factoid before you leave

Now this is for coding cocktail party chatter - did you notice that one of the -only methods was ? This would turn into a hash with indifferent access, which you can do anything to that you would with any old piece of nested data. Use your power wisely.

Photo by Elias Castillo on Unsplash

I hope sharing what I may understand about has helped you in some way. Please let me know if anything seems off, and then we’ll discuss and learn more!

Thanks to those involved in this exasperated Stack Overflow question on what are and this post on status as a hash or not, who all helped me sleep at night whether they know it or not.

Software Developer with social justice roots. I love cats, Star Trek, and singing to inspire the downtrodden.