开发者

Multilevel block methods in rails

I am making a view helper to render set of data in a format. I made these classes

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

helper is

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

builder is

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

column module is

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

Now i write code to test it

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

Every thing is working fine , age , contact , company is working fine. But phones for the contact is not showing.

Does any one have an idea, i know i have missed something in the code. Looking for your help.

Updated question with complete source is enter link description here


There are two issues I can see in the column module.

1) If a block is provided you're setting it to nil - so if block is always returning false. 2) Even if block wasn't nil you're just returning the block as the value, not actually passing control to the block. You should be calling block.call or yielding. Implicit blocks execute faster, so I think your column module should look more like this:

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


The solution is now posted in the discussion.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜