user1066183
user1066183

Reputation: 2584

rails_admin setting current_user in controller

I have a Event model:

class Event < ActiveRecord::Base
  belongs_to :author, class_name: 'User'
end

I can type in console:

e=Event.last
e.author

In rails_admin when I create a new Event I don't want to show the author_id field in the form. I want to set the author in the controller with something like this:

@e=Event.new(params)
@e.author_id=current_user.id
@e.save

Is possible to do it in rails_admin?

I have found this document in the official wiki, but i don't want to use the cancan ability and i don't want to set the author_id field with a hidden field in the form becouse is dangerous for the security, infact the POST request can be override with a custom author_id. I want simple assign the author_id in a controller. Is possible?

Upvotes: 3

Views: 2312

Answers (2)

Erick Maynard
Erick Maynard

Reputation: 801

pereleguine literally saved my ass today with his comment from 2 years ago. Thank you, thank you.

I had to make one modification and remove satisfy_strong_params! It's again pretty hacky, but it works:

RailsAdmin.config do |config|

config.actions do
dashboard                     # mandatory
index                         # mandatory

new do
  controller do
    proc do
      if request.get? # NEW

        @object = @abstract_model.new
        @authorization_adapter && @authorization_adapter.attributes_for(:new, @abstract_model).each do |name, value|
          @object.send("#{name}=", value)
        end
        if object_params = params[@abstract_model.to_param]
          @object.set_attributes(@object.attributes.merge(object_params))
        end
        respond_to do |format|
          format.html { render @action.template_name }
          format.js   { render @action.template_name, layout: false }
        end

      elsif request.post? # CREATE

        @modified_assoc = []
        @object = @abstract_model.new
        satisfy_strong_params!
        sanitize_params_for!(request.xhr? ? :modal : :create)

        @object.set_attributes(params[@abstract_model.param_key])
        @authorization_adapter && @authorization_adapter.attributes_for(:create, @abstract_model).each do |name, value|
          @object.send("#{name}=", value)
        end

        # customization
        if @object.class == Event
          # do whatever you want
        end                

        if @object.save
          @auditing_adapter && @auditing_adapter.create_object(@object, @abstract_model, _current_user)
          respond_to do |format|
            format.html { redirect_to_on_success }
            format.js   { render json: {id: @object.id.to_s, label: @model_config.with(object: @object).object_label} }
          end
        else
          handle_save_error
        end
      end       
    end
  end
end

export
bulk_delete
show
edit
delete
show_in_app

end

end

Upvotes: 0

peresleguine
peresleguine

Reputation: 2403

I didn't find clean way to do this in rails_admin. Here is an open issue: https://github.com/sferik/rails_admin/issues/1855.

This could be not the best option but you may override global logic in create action. Take a look how it works: https://github.com/sferik/rails_admin/blob/master/lib/rails_admin/config/actions/new.rb.

There is a register_instance_option :controller block. It means that you may pass this option through the config. More info here: https://github.com/sferik/rails_admin/wiki/Actions.

So if you really need it you can edit /config/initializers/rails_admin.rb:

RailsAdmin.config do |config|

  config.actions do
    dashboard                     # mandatory
    index                         # mandatory

    new do
      controller do
        proc do
          if request.get? # NEW

            @object = @abstract_model.new
            @authorization_adapter && @authorization_adapter.attributes_for(:new, @abstract_model).each do |name, value|
              @object.send("#{name}=", value)
            end
            if object_params = params[@abstract_model.to_param]
              @object.set_attributes(@object.attributes.merge(object_params))
            end
            respond_to do |format|
              format.html { render @action.template_name }
              format.js   { render @action.template_name, layout: false }
            end

          elsif request.post? # CREATE

            @modified_assoc = []
            @object = @abstract_model.new
            satisfy_strong_params!
            sanitize_params_for!(request.xhr? ? :modal : :create)

            @object.set_attributes(params[@abstract_model.param_key])
            @authorization_adapter && @authorization_adapter.attributes_for(:create, @abstract_model).each do |name, value|
              @object.send("#{name}=", value)
            end

            # customization
            if @object.class == Event
              # do whatever you want
            end                

            if @object.save
              @auditing_adapter && @auditing_adapter.create_object(@object, @abstract_model, _current_user)
              respond_to do |format|
                format.html { redirect_to_on_success }
                format.js   { render json: {id: @object.id.to_s, label: @model_config.with(object: @object).object_label} }
              end
            else
              handle_save_error
            end
          end       
        end
      end
    end

    export
    bulk_delete
    show
    edit
    delete
    show_in_app

  end
end

Upvotes: 6

Related Questions