如何将arbre代码干掉成可重用的组件?

时间:2014-06-24 14:46:04

标签: ruby-on-rails ruby ruby-on-rails-4 activeadmin arbre

我有一个常见的模式或重复的代码,我想在我的ActiveAdmin视图中干掉。我正在使用arbre组件来尽可能多地渲染我的视图,如果可能的话我想保持这种方式(即我不想以正常的方式转换为直接的HTML) - 我试图了解这里的arbre方式)。这是我想干的代码:

clients.in_groups_of(3).each do |clients_group|
  columns do
    clients_group.compact.each do |client|
      column do
        panel client.name do
          # ...
        end
      end
    end
  end
end

在阅读了arbre gem中的文档后,我开始尝试创建自己的自定义arbre组件。但我很快被迫意识到我不知道如何满足arbre。我无法弄清楚如何将我的局部变量传递到块中。例如:

# config/initializers/active_admin.rb

module ActiveAdmin
  module Views
    class ClientsBreakdown < ActiveAdmin::Component
      builder_method :clients_breakdown

      def build(clients, attributes = {})
        group_size = attributes.delete(:in_groups_of) { 3 }

        clients.in_groups_of(group_size).each do |clients_group|
          columns do
            clients_group.compact.each do |client|
              column do
                panel client.name do
                  super(attributes) # Doesn't seem to matter where this `super` call
                                    # is, but I do want to be able to pass `client`
                                    # into the `clients_breakdown` block here
                  # yield(client)   # -- I've also tried adding this.
                end
              end
            end
          end
        end
      end
    end
  end
end

然后,在我的ActiveAdmin用户视图中调用它可能如下所示:

clients_breakdown(Client.all, in_groups_of: 2) do |client|
  ul do
    li client.name
  end
end

运行上面的代码会导致此错误:

更新2 将自定义组件代码移至ActiveAdmin::Views模块后,异常已更改为此。

New Exception

我的关键问题似乎是我不能只调用yield(client)我目前拥有的super(attributes)。但这是一个arbre的东西所以我不知道该怎么做才能将客户端传递到调用块。这是正确的轨道还是有另一种方法来干这个?

更新1

我意识到对super的调用可能发生在build方法的任何地方,实际上与输出内容无关。因此,即使我移动super(attributes)调用...我仍然无法弄清楚要放在panel块内的内容,以便我可以在其中渲染其余的arbre组件致电clients_breakdown

1 个答案:

答案 0 :(得分:7)

这是一个潜在的解决方案。

要注意的一些事项super(attributes)应该,除非 ClientBreakdown Arbre组件正在输出自己的HTML。 Arbre组件 通常用于从头开始构建HTML,而不一定是 撰写组件。

module ActiveAdmin
  module Views
    class ClientsBreakdown < ActiveAdmin::Component
      builder_method :clients_breakdown

      def build(clients, attributes = {})
        group_size = attributes.delete(:in_groups_of) { 3 }

        clients.in_groups_of(group_size).each do |clients_group|
          columns do
            clients_group.compact.each do |client|
              column do
                panel client.name do
                  yield client
                end
              end
            end
          end
        end
      end
    end
  end
end

另一种方法是定义辅助方法以提供相同的方法 要包含在ActiveAdmin::Views::Pages::Base中的模块中的功能。 这是ActiveAdmin定义其辅助方法以构建各种视图的地方,例如attributes_table

module ClientsBreakdown
  def clients_breakdown(clients, attributes = {})
    group_size = attributes.delete(:in_groups_of) { 3 }

    clients.in_groups_of(group_size).each do |clients_group|
      columns do
        clients_group.compact.each do |client|
          column do
            panel client.name do
              yield client
            end
          end
        end
      end
    end
  end
end

# config/initializers/active_admin.rb
ActiveAdmin::Views::Pages::Base.include ClientsBreakdown