Inherited Resources and Manipulating the Parameter Hash

The Inherited Resources gem is very useful at de-cluttering our controller code. And the documentation is pretty great at telling us how we can manipulate this clutter within the conventions of the gem itself. For example, if we want to, we can easily change the redirect of a controller action.

Recently I wanted to manipulate the model parameters of the params hash in a controller that uses Inherited Resources. Changing the params hash is probably (that is, almost certainly) a bad idea, but what the heck. I couldn’t think of a better work around at the time. Here’s how I did it.

The issue: We want to manipulate the params hash of a controller that uses Inherited Resources

The solution: We overwrite the build_resource_params method. We first permit the parameter keys that we expect. Then we manipulate the model parameters to our whim, before returning it.

Despite being fairly familiar with Inherited Resources and its various overwrite options, I was stuck on this for quite a while. I kept getting an ActiveModel::ForbiddenAttributesError which means (surprise) that the attributes in our params hash have not been permitted.

Let’s say we have an Animal model and a corresponding AnimalsController. We want to modify the Animal parameters in the params hash. We’d need something like this as our build_resource_params:

class AnimalsController < ApplicationController
def build_resource_params
animal_params = params.fetch(:animal, {}).permit(:name, :age, :family)
def prepare_animal_params animal_params
# here we manipulate the model parameters however we want
# e.g. animal_params[:age] = 1 if animal_params[:age] < 0
# importantly this method must return the model params

And that’s it!

Note: if we had overwritten the permitted_params to allow our Animal parameters, this overwrite wouldn’t be needed any more as the permission step now happens in the build_resource_params.

Shift cipher gem

I’ve published my first gem, a shift (Caeser) cipher. As it stands, it’s a very simple, probably very flawed implementation (for one, it leaves punctuation in place), but I wanted to publish it sooner rather than later because carpe diem and all that.

And here it is on github.