Multi level block method is generating issue

后端 未结 2 1188
不知归路
不知归路 2021-01-03 14:26

I have a class

class DataListBuilder
    include ActionView::Helpers::TagHelper
    include ActionView::Helpers::CaptureHelper
    include ActionView::Helper         


        
相关标签:
2条回答
  • 2021-01-03 15:27

    options_column is a "block view", I'd remove the = in <%= l.options_column do |c| %>, that's for sure. Then, I'd use concat in options_column instead of returning it directly as a string.

    Anyway, the simple solution is here (I've used it, no problems at all):

    https://github.com/markevans/block_helpers

    0 讨论(0)
  • 2021-01-03 15:31

    First of all we refactored your helper for more intensive usage of content_tag (just to get whats going in this code ^_^).

    Next we add usage of output_buffer which was defined but not used at all in helper.

    After it all methods wich should be called from erb should return nil so they didn't appear in HTML.

    And last syntactic suger was usage of instance_eval so you don't need {|c| ...} style blocks. You can use all variables from DataListBuilder directly there.

    module DataListHelper
      def list_headers(args=[])
        args    = Array.new(args)
        columns = []
        args.map { |o| columns << content_tag(:li, o.split(":").first, :style=>"width:#{o.split(":").second}px;") }
        content_tag(:ul, columns.join(" ").html_safe, :class=>"list-headers")
      end
    
      def data_list_total_records(array)
        content_tag(:div, page_entries_info(array).html_safe, :class=>"total-records")
      end
    
      def data_list_for(object, headers=[], &block)
    
        if object.is_a? Array
          if object.length == 0
            list_headers(headers).concat(content_tag(:strong, "<br />No records found".html_safe))
          else
            res_obj = data_list_total_records(object)
            res_obj << content_tag(:ol, :class=>"data-list") do
              res_ol = content_tag(:li) do
                res = list_headers(headers)
                object.each do |o|
                  builder = DataListBuilder.new(o)
                  res << content_tag(:li) do
                    content_tag(:ul, :id=>o.id, :class=>"list-row #{cycle('odd', 'even')}") do
                      capture(builder, &block)
                      builder.output_buffer.html_safe
                    end
                  end
                end
                res
              end
              res_ol << data_list_pagination(object)
            end
            res_obj
          end
        else
          list_headers(headers).concat(content_tag(:strong, " <br />Not available."))
        end
      end
    
      class DataListBuilder
        include ActionView::Helpers::TagHelper
        include ActionView::Helpers::CaptureHelper
        include ActionView::Helpers::UrlHelper
        include Rails.application.routes.url_helpers
    
        attr_accessor :object, :output_buffer, :controller
    
        def initialize(object)
          @object, @output_buffer = object, ''
        end
    
        def column (&block)
          @output_buffer << if block_given?
            content_tag(:li, instance_eval(&block))
          else
            content_tag(:li, "")
          end
          nil
        end
    
        def options_column(&link_block)
          @output_buffer << if block_given?
            content_tag(:li) do
              content_tag(:dl, :class=>'options') do
                res = content_tag(:dt) do
                  content_tag(:a, '&nbsp;'.html_safe, :href => '#')
                end
                res << content_tag(:dd) do
                  content_tag(:ul) do
                    instance_eval &link_block
                  end
                end
              end
            end
          else
            content_tag(:li, "")
          end
          nil
        end
    
        def link_item(title, url, options={})
          content_tag :li, link_to(title, url, options)
        end
      end
    end
    

    And your view became this:

    <%= data_list_for @leads, [" :10", "Age:30", "Contact:140", "Phone:140", "Email:180", "Company:100", ""] do |l| %>
        <%= l.column { link_to "&nbsp;".html_safe, "leads/details/#{object.id}", :class=>:plus, :remote=>true } %>
        <%= l.column { object.age } %>
        <%= l.column { object.contact.complete_name } %>
        <%= l.column { object.contact.phones.blank? ? "-" : object.contact.phones.first.phone_number } %>
        <%= l.column { object.contact.emails.blank? ? "-" : object.contact.emails.first.email } %>
        <%= l.column { object.company.title } %>
        <%= l.options_column do %>
            <%= link_item 'Show', lead_path(object.id) %>
            <%= link_item 'Edit', edit_lead_path(object.id) %>
            <%= link_item 'New Note', "leads/#{object.id}/notes/new", :class=>"display-newxdoc", :id=>object.id %>
            <%= link_item 'Create Opportunity', new_lead_opportunity_path(object.id) %>
        <% end %>
    <% end %>
    
    0 讨论(0)
提交回复
热议问题