The ideas here are interesting, but one peeve I have is that it compares the best example of functional strong params with the worst example of regular params. It’s saying
But it does three things to make the original look worse. First it adds the params.permit bit to the original but not the final version, which adds cruft. Second, it’s using hash rockets instead of colon syntax, which adds a lot of cruft. Finally, in the ‘functional’ style the author is using a helper variable, while everything’s inline in the original case. Cleaning everything up, you’d actually be comparing it to this:
I find this approach really interesting. Personally, From a RoR perspective, I find this approach the easiset to maintain and to read. It keeps the important bits of the logic isolated into its own namespace and keeps the application fairly clutter free.
First set a memoized helper in the application_controller.rb called permitted_params. This will now be accessible in the controllers.
I’ll then have a separate folder for all of the strong params logic. Within the folder, I’ll create a new params for each ActiveRecord model.
app/params/params.rb
class Params::PermittedParams < Struct.new(:params, :current_user)
include Params::User
end
Since our permitted_params helper takes in the params and the current_user, we can use that in our user.rb methods. I’ll access the params and first required the [:user] parameter to exist and then permit from a private method called user_attributes.
This private method will return an array. We can build out the allowed parameters here as well as having access to limit what parameters a user can write to. In this case, I would only allow the admin attribute to be written to by user input if the current user is already an admin.
# app/params/user.rb
module Params
module User
def user
params.require(:user).permit(*user_attributes)
end
private
def user_attributes
[].tap do |attributes|
attributes << :first_name
attributes << :last_name
attributes << :admin if current_user.admin?
end.flatten
end
end
end
I’ve used it in small apps as well as larger ones and it’s kept the code fairly clean. Since it’s also leveraging memoization, having it called multiple times in a controller/view/presenter keeps the footprint the same. I would probably have a concern if my app had thousands of AR models, but so far it’s been pretty efficient.
The ideas here are interesting, but one peeve I have is that it compares the best example of functional strong params with the worst example of regular params. It’s saying
is better than
But it does three things to make the original look worse. First it adds the
params.permitbit to the original but not the final version, which adds cruft. Second, it’s using hash rockets instead of colon syntax, which adds a lot of cruft. Finally, in the ‘functional’ style the author is using a helper variable, while everything’s inline in the original case. Cleaning everything up, you’d actually be comparing it to this:Which is a lot cleaner than the functional version.
I find this approach really interesting. Personally, From a RoR perspective, I find this approach the easiset to maintain and to read. It keeps the important bits of the logic isolated into its own namespace and keeps the application fairly clutter free.
First set a memoized helper in the application_controller.rb called permitted_params. This will now be accessible in the controllers.
Within the controllers, I can use
permitted_params.userinstead of theparams.I’ll then have a separate folder for all of the strong params logic. Within the folder, I’ll create a new params for each ActiveRecord model.
Since our
permitted_paramshelper takes in the params and the current_user, we can use that in our user.rb methods. I’ll access the params and first required the [:user] parameter to exist and then permit from a private method called user_attributes.This private method will return an array. We can build out the allowed parameters here as well as having access to limit what parameters a user can write to. In this case, I would only allow the admin attribute to be written to by user input if the current user is already an admin.
So this object ends up being a sort of global registry of params logic per-model? Hmm, I have some thoughts around this, thanks for sharing!
I’ve used it in small apps as well as larger ones and it’s kept the code fairly clean. Since it’s also leveraging memoization, having it called multiple times in a controller/view/presenter keeps the footprint the same. I would probably have a concern if my app had thousands of AR models, but so far it’s been pretty efficient.