What's the problem?
Say we have a dashboard:
- With two has_many associations.
- Only one of them listed in the collection (eg: the table in index page).
- Both listed in the show page.
Now lets say:
- Go to the show page.
- Of the two associations, click to paginate on the one that does not appear in the collection listing.
You'll get an unpermitted parameters exception.
Why does it do that?
The root of the problem is at app/views/administrate/application/_collection.html.erb
:
- In this template, the headers are rendered as links that allow users to change the order of the records.
- To do this, these links must include query params.
- There might be query params in play already that we don't want to lose, so we have to add to the existing query params.
- Because we need the list of query params currently in play, we have to read these from
params
. -
params
is an instance ofActionController::Parameters
, so we can't simply merge as it was a Hash. We need to read each desired param explicitly with#permit
. (OK, we could to#to_unsafe_h
, but that's bad form).
When doing 5, the explicit list of params that are permitted is extracted from COLLECTION_ATTRIBUTES
, leaving out those attributes that appear in the show page and not in the collection.
How am I fixing it?
To be honest, I could just merge with #to_unsafe_h
and be done with it, but I feel bad about it. On the other hand, I don't know what the problem would be. This is reading params to create a query string, not to generate SQL, so it shouldn't be a security concern. Perhaps I'm missing something?
Anyway, I'm creating a distinction between "includes" (ie: has_many associations) that are part of the collection or of the individual item's show page; then I'm using the latter when reading the query params for those links.