Rails_admin,如何为自定义操作创建表单?

Rails_admin, how to create forms for custom actions?

我已经生成了自定义操作 by this link on wiki。我创建了 class 继承自 RailsAdmin::Config::Actions::Base.

我已在 rails_admin_my_action/app/views/rails_admin/main/my_action.html.erb

中创建此操作的视图

当我们为您的控制器创建表单时,我们主要使用 form_for 它将转到我的控制器并执行特定操作,但我认为在 rails_admin 中还有其他东西,因为 rails_admin 使用他自己的控制器,该控制器是从 RailsAdmin::Config::Actions::Base.

生成的

如何为我的自定义 rails_admin 操作创建表单?

我问这个是因为没有关于此的适当文档。

我对我的行为的看法是这样的:

<h3>Manage state of <%= @object.name %></h3>
<div class="btn-group" data-toggle="buttons">

  <% @object.state_events.each do |event| %>
      <label class="btn bnt-lg btn-default">
        <%= form.radio_button :state, event, autocomplete: 'off' %> <%= event %>
      </label>

<% end %>


</div>

<br/>

<hr/>

<%= form.submit 'Change', class: 'btn btn-lg btn-primary'  %>

lib/my_action.rb 中,我刚刚复制了 edit 操作的 register_instance_option :controller

当我提交表单时。我收到 ActiveModel::ForbiddenAttributesError 错误。

这取决于您的操作,因此 take a look how templates are implemented. Basically form_tag my_action_path or form_for @object, url: my_action_path(@abstract_model, @object.id) should work. FYI you may define custom action 就在 rails_admin 配置中:

RailsAdmin.config do |config|
  config.actions do
    member :my_action do
      only ['MyModel']
      http_methods { [:post, :get] }

      controller do
        proc do
          if request.get?
          elsif request.post?
          end
        end
      end

    end
  end
end

您可以利用 Rails 管理员的控制器而不是实现您自己的控制器,例如如果您只需要为自定义操作自定义表单而不涉及其他逻辑。

为此,在添加实际的 Action 之后,您还需要添加一个 Section,方法相同,但继承自 RailsAdmin::Config::Sections::Base.

因此,如果您的自定义操作在 lib 目录中被调用 "Cancel",您可能会有这样的内容:

rails_admin/
└── config/
    └── actions/
    │   └── cancel.rb
    └── sections/
        └── cancel.rb

您的操作可以如下:

require 'rails_admin/config/actions'
require 'rails_admin/config/actions/edit'

module RailsAdmin
  module Config
    module Actions
      class Cancel < Edit
        RailsAdmin::Config::Actions.register(self)

        register_instance_option :link_icon do
          'fa fa-ban'
        end
      end
    end
  end
end

如您所见,您不必实现控制器 Proc,它将继承自默认 "Edit" 操作。

部分代码看起来很简单,这是我的代码:

require 'rails_admin/config/sections'
require 'rails_admin/config/sections/edit'

module RailsAdmin
  module Config
    module Sections
      class Cancel < Edit
      end
    end
  end
end

并且在 rails_admin.rb:

require "rails_admin/config/actions/cancel"
require "rails_admin/config/sections/cancel"

现在让我们看一下RailsAdmin::Config::Sections,它实现了.included方法,这就是为什么此时什么都不起作用的原因;)

此模块包含在 RailsAdmin::Config::Model 中,并定义了您用来定义配置中的部分的这些配置方法:listeditupdate 等。并且您的自定义部分不起作用,因为 .included 在您的新部分加载之前执行。

为了解决这个问题,我为 RailsAdmin::Config::Model 添加了一个补丁,它会在我所有的自定义部分加载后再次执行该方法。这是代码(不是最好的方法,但我太懒了):

module RailsAdmin
  module Config
    class Model
      # Re-execute included(self) to register custom sections
      RailsAdmin::Config::Sections.included(self)
    end
  end
end

更好的选择是实现 .register 方法,就像 RailsAdmin::Config::Actions 那样,而不是重新定义已经存在的方法。

那么您的 rails_admin.rb 将如下所示:

require "rails_admin/config/actions/cancel"
require "rails_admin/config/sections/cancel"
require "monkey/rails_admin/config/model"

RailsAdmin.config do |config|
  config.actions do
    # ...
    cancel
  end

  config.model "ModelName" do
    cancel do
      field :name
    end
  end
end

就是这样,现在您可以在 cancel.haml 中添加(从默认编辑模板复制):

= rails_admin_form_for @object, url: edit_path(@abstract_model, @object.id), as: @abstract_model.param_key, html: { method: "put", multipart: true, class: "form-horizontal denser", data: { title: @page_name } } do |form|
  = form.generate action: :cancel

此处唯一的区别是传递给 #generate 的操作名称。 Rails 管理员将为您生成表格并将其提交给自己的 "Main" 管理员。如果您需要向操作添加一些自定义逻辑,那么您可以在操作中实现控制器 proc,它将被调用。

玩得开心!