Многоуровневые блочные методы в рельсах - PullRequest
1 голос
/ 25 марта 2011

Я делаю помощник вида для рендеринга набора данных в формате.Я сделал эти классы

require 'app/data_list/helper'

module App
  module DataList
    autoload :Builder, 'app/data_list/builder'
     @@data_list_tag = :ol
     @@list_tag      = :ul
    end
end
ActionView::Base.send :include, App::DataList::Helper

Помощник

module App
  module DataList
    module Helper

      def data_list_for(object, html_options={}, &block)

        builder     = App::DataList::Builder
        arr_content = []
        object.each do |o|
          arr_content << capture(builder.new(o, self), &block)
        end
        content_tag(:ol, arr_content.join(" ").html_safe, html_options).html_safe
      end
    end
  end
end

Строитель

require 'app/data_list/column'

module App
  module DataList
    class Builder
      include App::DataList::Column
      include ActionView::Helpers::TagHelper
      include ActionView::Helpers::AssetTagHelper

      attr_reader :object, :template

      def initialize(object, template)
        @object, @template = object, template
      end

      protected

      def wrap_list_item(name, value, options, &block)
        content_tag(:li, value).html_safe
      end

    end
  end
end

Модуль столбца

module App
  module DataList
    module Column
      def column(attribute_name, options={}, &block)
        collection_block, block = block, nil if block_given?

        puts attribute_name

        value = if block
                  block
                elsif @object.respond_to?(:"human_#{attribute_name}")
                  @object.send :"human_#{attribute_name}"
                else
                  @object.send(attribute_name)
                end

        wrap_list_item(attribute_name, value, options, &collection_block)
      end
    end
  end
end

Теперь я пишукод для проверки

 <%= data_list_for @contracts do |l| %>
        <%= l.column :age %>
        <%= l.column :contact do |c| %>
            <%= c.column :phones %>
        <% end %>
        <%= l.column :company %>
    <% end %>

Все работает нормально, age, contact, company работает нормально.Но phones для contact не отображается.

У кого-нибудь есть идея, я знаю, что что-то пропустил в коде.Нужна ваша помощь.

Обновленный вопрос с полным источником введите описание ссылки здесь

Ответы [ 2 ]

1 голос
/ 28 марта 2011

Есть две проблемы, которые я вижу в модуле столбца.

1) Если предоставляется блок, вы устанавливаете его в ноль - так что if block всегда возвращает false2) Даже если block не равно нулю, вы просто возвращаете блок как значение, а не передаете управление блоку.Вы должны звонить block.call или уступать.Неявные блоки выполняются быстрее, поэтому я думаю, что ваш модуль столбца должен выглядеть примерно так:

module DataList
  module Column
    def column(attribute_name, options={})

      value = begin
        if block_given?
          yield self.class.new(@object.send(attribute_name), @template)
        elsif @object.respond_to?(:"human_#{attribute_name}")
          @object.send :"human_#{attribute_name}"
        else
          @object.send(attribute_name)
        end
      end

      wrap_list_item(attribute_name, value, options)
    end
  end
end
0 голосов
/ 07 апреля 2011

Решение опубликовано в обсуждении .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...