ruby-on-rails - 如何将 arbre 代码干燥成可重用的组件?

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

我有一个共同的模式或重复的代码,我想在我的 ActiveAdmin View 中干掉。我正在使用 arbre组件来尽可能多地呈现我的 View ,如果可能的话我想保持这种方式(即我真的不想以正常方式转换为直接 HTML - 我正在尝试理解这里是树荫路)。这是我想干掉的代码:

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。我不知道如何将局部变量传递到 block 中。例如:

# 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 用户 View 中调用它可能如下所示:

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

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

更新 2 在将我的自定义组件代码移动到 ActiveAdmin::Views 模块后,异常已更改为这个。

New Exception

我的关键问题似乎是我不能只在我目前拥有 super(attributes) 的地方调用 yield(client)。但那是一件很麻烦的事情,所以我不知道该怎么做才能将客户端传递到调用 block 中。这是正确的 rails 还是有其他方法可以解决这个问题?

更新 1

我已经意识到对 super 的调用可以发生在 build 方法中的任何地方,并且实际上与输出的内容无关。所以即使我移动 super(attributes) 调用...我仍然无法弄清楚要在 panel block 中放置什么以便我可以渲染调用 clients_breakdown 后,我的其余 arbre 组件就在那里。

最佳答案

这是一种可能的解决方案。

需要注意的几件事是 super(attributes) 应该被调用,除非 ClientBreakdown Arbre 组件正在输出它自己的 HTML。乔木组件 通常用于从头开始构建 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 定义其辅助方法来构建各种 View 的地方,例如 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

关于ruby-on-rails - 如何将 arbre 代码干燥成可重用的组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24389647/

相关文章:

css - 未定义的表单样式

ruby-on-rails - 具有多个数据库的 Rails 6,基于读取或创建查询自动更改连接

ruby - 使用正则表达式的 `String#split` 方法的不同返回值

c# - ruby 中的 hmac-sha1 不同于 C# HMACSHA1

ruby-on-rails - Rails Friendly_id唯一子弹格式

ruby-on-rails - 确定 Rails after_save 回调中更改了哪些属性?

ruby-on-rails - 将密码重置发送到其他电子邮件 - Devise

ruby-on-rails - 为什么我应该使用 Ruby on Rails?

ruby-on-rails - 将html表的值提交给 Controller ruby中的变量

javascript - 滚动条隐藏在 rails 4 中