2011-03-25 2 views
1

Je crée un assistant d'affichage pour rendre un ensemble de données dans un format. J'ai fait ces classesMéthodes de blocs multiniveaux dans les 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 

aide est

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 
constructeur

est

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 colonne

est

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 

Maintenant, j'écrire du code pour tester

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

Tout fonctionne très bien, age, contact, company fonctionne très bien. Mais phones pour le contact n'est pas à l'affiche.

Est-ce que quelqu'un a une idée, je sais que j'ai manqué quelque chose dans le code. Vous cherchez votre aide.

question Mise à jour avec une source complète est enter link description here

Répondre

1

Il y a deux questions que je peux voir dans le module de colonne.

1) Si un bloc est fourni, vous le définissez à zéro - alors if block retourne toujours faux. 2) Même si block n'était pas nul, vous renvoyez simplement le bloc comme valeur, sans passer le contrôle au bloc. Vous devriez appeler block.call ou céder. blocs Implicite exécuter plus rapidement, donc je pense que votre module de colonne devrait ressembler à ceci:

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

Merci pour l'aide, mais il génère une erreur. sur la ligne '<% = c.column: phones%>' il génère une erreur 'ActionView :: Template :: Error (méthode non définie' column 'pour nil: NilClass): ' –

+0

try' yield self' à la place. – mnelson

+0

Maintenant, l'erreur a changé 'ActionView :: Template :: Error (méthode non définie' phones 'pour # ): ' –

0

La solution est maintenant affichée dans le discussion.