What is the proper way to set strong parameters in a Rails controller and using validators with them? I've seen several examples of doing this several different ways.
This is what a typical controller def looks like for me:
# User model
class User < ActiveRecord::Base
validates :first_name, length: { in: 2..50 }, format: { with: /[a-zA-Z0-9\s\-\']*/ }
validates :last_name, length: { in: 2..50 }, format: { with: /[a-zA-Z0-9\s\-\']*/ }
validates :email, presence: true, length: { 5..100 }, format: { with: /**email regex**/ }, uniqueness: { case_sensitive: false }
end
# Controller def
def valid_email
# Strong parameters defined here? When is an error thrown for unmatched requires/permits?
params.require(:user)
params[:user].permit(:email)
# How to prevent blank params[:user][:email] from making unnecessary database call if it's blank?
@user = User.find_by(email: params[:user][:email])
unless @user.nil?
# Should work because in permit whitelist?
@user.assign_attributes(email: params[:user][:email])
# Should not work because not in permit whitelist?
@user.assign_attributes(first_name: params[:user][:first_name])
# Should work just sending to private def
@user.assign_attributes(savable_params)
# Validate entire model
if @user.valid?
@user.save
end
end
rescue => e
log_error(e)
render text: "Something bad happened. Contact support.", status: :unprocessed_entity
end
private def savable_params
params.require(:user).permit(:email)
end
How I understand it, is the params.require and params.permit allow for whitelisting of data passed to the controller/action, but doesn't keep "other" data from being seen in the params list (if it's passed).
So, leads into a few questions:
- Proper way of whitelisting in a similar scenario a top?
- How would you, say for instance, make sure params[:user][:email] isn't blank ("") before trying to do a User.find_by since we know that a blank email isn't valid anyway and do not want to make an unnecessary database call?
- User.valid? will validate the entire model, even though I'm interested in only the :email attribute be valid before doing a User.find_by?
- If you have the uniqueness validator on email, for instance, how would you keep uniqueness from hitting the database, if params[:user][:email] is blank and we're only interested in that email isn't blank, fits within a certain length, and matches the format?
Thanks again.