Skip to content

Instantly share code, notes, and snippets.

@danielpuglisi
Last active August 9, 2021 12:33
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save danielpuglisi/3c679531672a76cb9a91 to your computer and use it in GitHub Desktop.
Save danielpuglisi/3c679531672a76cb9a91 to your computer and use it in GitHub Desktop.
Rails examples: Single Table Inheritance (STI), strong parameters, single controller.
# Variant 1
def user_params(type)
params.require(type.to_sym).permit(attributes)
end
# Variant 2
def user_params(type)
case type
when "user"
params.require(:user).permit(user_attributes)
when "apprentice"
params.require(:apprentice).permit(apprentice_attributes)
end
end
# Variant 3
def update
...
if @user.update(send("#{@user.type.underscore.to_sym}_params"))
...
end
def user_params
params.require(:user).permit(attributes)
end
def apprentice_params
params.require(:apprentice).permit(attributes)
end
# Variant 4
https://github.com/T-Dnzt/sti-with-rails4/blob/master/app/controllers/animals_controller.rb
@vinagrito
Copy link

If the list gets too long I took an approach where I defined the permitted attributes in every model

# products_controller.rb
def product_class
 @product_class ||= params[:product][:type].camelcase.constantize
end
def create
  product_class.new product_params
end

def product_params
  @product_params ||= product_class.permitted_attributes_from_params(params[:product])
end
# product/product_a.rb 
class ProductA < Product
 def self.permitted_attributes_from_params(params)
  parameters = ActionController::Parameters.new(params)

  parameters.permit(:name, :price).tap do |whitelisted|
    whitelisted[:hash_attribute] = params[:hash_attribute] # this is in case the hash keys are dynamic
  end
 end
end

Again, this approach is for when the possible amount of permitted gets crazy big cause of STI.

@aalvrz
Copy link

aalvrz commented Nov 17, 2015

Thank you this worked wonderfully!

@dinkengraven
Copy link

Just stumbled upon this and found a handy solution for my problem, thank you :)

@flavio-b
Copy link

flavio-b commented Jun 8, 2018

Thanks! To get the name of the model used in the parameters, you can also use:
@model_instance.model_name.param_key

@jonatassalgado
Copy link

And what about that?

def user_params
    type = @user.type.underscore.to_sym
    params.require(type).permit(:name, :age)
end

@adriancb
Copy link

adriancb commented Aug 9, 2021

Thanks! To get the name of the model used in the parameters, you can also use:
@model_instance.model_name.param_key

👍 - cleanest IMO. Thanks @flavio-b!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment