2011-03-25 47 views
1

我正在製作一個視圖幫助器來呈現一組格式的數據。我做了這些類rails中的多級塊方法

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工作正常。但phonescontact沒有顯示。

有沒有人有一個想法,我知道我錯過了代碼中的東西。尋找你的幫助。

完整的源更新的問題是enter link description here

回答

1

有兩個問題,我可以列模塊中看到。

1)如果提供了塊,則將其設置爲零 - 因此if block總是返回false。 2)即使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

感謝您的幫助,但它產生了一些錯誤。 on line'<%= c.column:phones%>'它會產生錯誤'ActionView :: Template :: Error(nil:NilClass的未定義方法列):' – 2011-03-29 08:44:36

+0

嘗試'yield self'代替。 – mnelson 2011-03-29 15:26:49

+0

現在錯誤已經改變了'ActionView :: Template :: Error(undefined method'phone'for#):' – 2011-03-30 11:52:16