Given the following setup(which is not working currently)
class Employee < ActiveRecord::Base
end
class Manager < Employee
end
ActiveAdmin.register Employee do
  form do |f|
    f.input :name
    f.input :joining_date
    f.input :salary
    f.input :type, as: select, collection: Employee.descendants.map(&:name)
  end
end
I would like to have a single "new" form for all employees and be able to select the STI type of the employee in the form. I am able to see the select box for "type" as intended but when I hit the "Create" button, I get the following error:
ActiveModel::MassAssignmentSecurity::Error in Admin::EmployeesController#create
Can't mass-assign protected attributes: type
Now, I am aware of the way protected attributes work in Rails and I have a couple of workarounds such as defining Employee.attributes_protected_by_default but that is lowering the security and too hack-y.
I want to be able to do this using some feature in ActiveAdmin but I can't find one. I do not want to have to create a custom controller action as the example I showed is highly simplified and contrived.
I wish that somehow the controller generated by ActiveAdmin would identify type and do Manager.create instead of Employee.create
Does anyone know a workaround?
You can customize the controller yourself. Read ActiveAdmin Doc on Customizing Controllers. Here is a quick example:
controller do
  alias_method :create_user, :create
  def create
    # do what you need to here
    # then call create_user alias
    # which calls the original create
    create_user
    # or do the create yourself and don't
    # call create_user
  end
end
                        Newer versions of the inherited_resources gem have a BaseHelpers module. You can override its methods to change how the model is altered, while still maintaining all of the surrounding controller code. It's a little cleaner than alias_method, and they have hooks for all the standard REST actions:
controller do
  # overrides InheritedResources::BaseHelpers#create_resource
  def create_resource(object)
    object.do_some_cool_stuff_and_save
  end
  # overrides InheritedResources::BaseHelpers#destroy_resource
  def destroy_resource(object)
    object.soft_delete
  end
end
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With