Rails 3. 如何添加一个ActiveAdmin将使用的帮助程序?

69

我正在创建一个用于Formtastic的帮助程序,但是我遇到了“未定义的局部变量或方法”错误。我不知道在哪里放置它才能起作用。

我已经尝试将其放置在application_helper.rb和app/helpers/active_admin/view_helpers.rb中。


1
在我看来,ApplicationHelper 是自动加载的,但是我需要重新启动我的应用程序才能让 ActiveAdmin 检测到任何新的帮助程序。 - Besi
10个回答

76
你可以像你尝试过的那样在app/helpers/中定义它们,但你需要通过active admin的初始化程序将它们包含进来,就像这样:

您可以在app / helpers /中定义它们,但您需要通过Active Admin的初始化程序将它们包含进来,就像这样:

# in config/initializers/active_admin.rb
ActiveAdmin.setup do |config|
    ....
end

module ActiveAdmin::ViewHelpers
  include ApplicationHelper
end

这个解决方案乍一看似乎可行,但最终导致管理员登录页面出现冲突。我认为这种冲突是由于来自用户界面应用程序的 Devise helpers 引起的。@alony 的解决方案对我有用,尽管如果您正在重用来自用户界面应用程序的 helpers,则不会像这个方法那么干燥。也许,如果你在这个方法中包含一个除了 ApplicationHelper 以外的 helper,冲突就不会发生了? - Ryan Francis
这对我来说在Rails 4.2仍然有效。我找不到任何冲突,而且我正在使用Devise。但是我没有管理员登录页面 - 我有一个用户模型用于消费者和管理员。 - armchairdj
1
在我的环境下,使用 Rails 5.1.6 和 ActiveAdmin 1.3.0 工作正常。 - Tony Vincent

68
你需要将你的帮助函数放在 app/helpers/active_admin/views_helper.rb 文件中。 示例:

module ActiveAdmin::ViewsHelper #camelized file name
  def my_helper 
       # do something 
  end 
end 

25
一个小提示:在0.5.0版本中,您需要重新启动整个堆栈才能使其正常工作。 - Dmitry Polushkin
1
谢谢Dmitry。我差点放弃了,然后我意识到我需要重新启动 :) - Venkat D.
3
@DmitryPolushkin,1.0.0.pre。我最终做了bishma-stornelli建议的事情。至少它不依赖于一些AA开发人员无法抵制定期更改的虚幻约定。 - Gunchars
如果您想在集合操作中使用此辅助方法,请执行以下操作:controller do include ActiveAdmin::ViewsHelper end collection_action :my_action do render json: my_helper end - Lev Lukomsky
在ActiveAdmin 1.0.0.pre4中,"module ActiveAdmin::ViewHelpers"不起作用,但是根据这个答案所解释的,"module ActiveAdmin::ViewsHelper"起作用了。而且,我也必须重新启动整个堆栈。感谢@alony! - Chris Simeone

34
我发现使用ActiveAdmin 0.6.1时,ActiveAdmin会在app/helpers/active_admin/*_helper.rb中查找帮助程序,但是名称并不重要
重要的是:
  1. 文件名必须以“_helper.rb”结尾
  2. 模块名称必须是文件名的驼峰式大小写
  3. 该文件必须在app/helpers/active_admin/目录下
如果有人知道官方文档在哪里,那就太好了。
以下是示例:https://gist.github.com/afred/7035a657e8ec5ec08d3b

12
app/helpers/active_admin/view_helpers.rb

这没有帮助到我。

编辑:我已经更改了views_helper.rb和ViewsHelper,并相应地进行了更改,这样就可以了。

*但是如果你想只为某些资源定义它,你可以按照我的方式来做。


我不得不定义它。

#app/helpers/active_admin/categories_helper.rb

module ActiveAdmin::CategoriesHelper

  def helper_method

  end

end

针对我的 active_admin 资源 app/admin/categories.rb


7
另一种方法是使在幕后生成的特定ActiveAdmin控制器包括这个帮助程序。 这种方法允许根据文件明确地包含帮助程序,而不是全局性地包含。
ActiveAdmin.register MyModel do
  controller do
    include MyHelper
  end
end

如果您想在Active Admin和应用程序的其他部分中使用一些逻辑,这将非常有用。 - omnikron

5

我可以在ActiveAdmin 0.6.1中使其正常工作(终于!)。解决方案是创建一个帮助模块,如下所示:

# app/helpers/active_admin_helpers.rb
module ActiveAdminHelpers
  # make this method public (compulsory)
  def self.included(dsl)
    # nothing ...
  end

  # define helper methods here ...
  def helper_method
    ...
  end
end

然后以这种方式包含该模块:

# app/admin/[resource].rb
include ActiveAdminHelpers

ActiveAdmin.register [Resource] do
  ...

end

实际上,这不是一个很好的解决方案,但它是DRY且运行良好的。我已经阅读并尝试了许多方法和解决方案,例如ViewHelpers模块(放置在'app/helpers'或'app/admin/active_admin'下)、ActiveAdmin::DSL猴子补丁等等,但这些都没有在0.6.1版本中起作用(我对其他版本没有任何想法):(


7
这个方案从技术上来说是可行的,但并不明智。实际上你是在顶层将ActiveAdminHelpers包含到了Object中。这意味着一旦该文件被加载,这些辅助方法将在整个应用程序中的每个对象上都可用 - Peeja
4
事实上这是一个很糟糕的想法。将辅助函数包含在全局范围内会以意想不到和难以跟踪的方式造成混乱...我现在正在遭受它的困扰... :( - rewritten
1
我刚刚检查了我们的应用程序,并修复了一个问题,其中开发人员像那样进行了全局包含..绝对不是一个好的做事方式。 - Urkle

4
app/admin/active_admin/view_helpers.rb中定义ActiveAdmin::ViewHelpers对于我而言可以在activeadmin 0.3.40.5.0版本下运行。请注意,保留了HTML标签,但不提供解释。

3

使用来自git://github.com/activeadmin/activeadmin.git的activeadmin 1.0.0.pre1

Rails 4.2.1

这对我有效...

my_app/app/helpers/active_admin/resources_helper.rb

module ActiveAdmin
  module ResourcesHelper
    def resource_form_for(_resource, _params, _options = {}, &_block)
      url = if _resource.new_record?
              UrlBuilder.resources_path(_resource.class, _params)
            else
              UrlBuilder.resource_path(_resource.class, _params)
            end

      method = _resource.new_record? ? :post : :put

      options = { url: url, method: method, builder: ActiveAdmin::FormBuilder }
      options.merge!(_options)

      semantic_form_for([:admin, _resource], options) do |f|
        _block.call(f)
      end
    end
  end
end

my_app/app/admin/balance_sheets.rb

ActiveAdmin.register BalanceSheet do
  form partial: 'form'
end

my_app/app/views/admin/balance_sheets/_form.html.erb

<%= resource_form_for(resource, params) do |f| %>
  <%= f.inputs "Fields" do %>
    <%= f.input :progress_status %>
    <%= f.input :crew %>
    <%= f.input :shift %>
    <%= f.input :expected_progress %>
    <%= f.input :real_progress %>
    <%= f.input :analyst, collection: User.analysts %>
    <%= f.input :activity_ids, as: :check_boxes, collection: Activity.balance_sheet_activities %>
    <%= f.input :worker_ids, as: :check_boxes, collection: Worker.all %>
  <% end %>
  <%= f.actions %>
<% end %>

2
你也可以使用 ActiveAdmin partials :
``` render partial: 'admin/my_partial', locals: { var: my_var } ```
在 `app/views/admin/_my_partial.html.arb` 中写入你的 ActiveAdmin Ruby 代码。

1
我的解决方法是针对Rails 3.2.11版本和activeadmin (0.5.1) gem包,不需要添加app/active_admin/view_helpers.rb文件,或在config/initializers/active_admin.rb中声明任何模块。
我把助手逻辑上放置在app/*_helpers.rb文件中,根据model进行分类。然后在app/admin/model.rb文件中使用:
# app/admin/[resource].rb
ActiveAdmin.register [Resource] do
  ...
  filter :gender, as: :select, collection: proc{genders}
  ...
end

为了在过滤器中使用助手,在列表视图中显示一个下拉菜单以过滤性别。对应的创建表单字段,我使用了:

# app/admin/[resource].rb
ActiveAdmin.register [Resource] do
  form do |f|
    f.inputs "Case Manager" do
      ...
      f.input :gender, as: :radio, collection: genders
      ...
      f.buttons
    end
  end
end

显示输入表单的单选按钮。
不确定为什么在form do |f|块之外需要proc{},但如果有人能解释为什么这是个坏主意,我会找到另一种方法。

因为proc会使得内部代码稍后被评估。我认为aa在启动时正在加载admin/*类,有时存在未满足的依赖关系。因此,使用proc可以告诉代码在所有内容加载完成后再执行。 - Ivailo Bardarov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接