Search code examples
rubyruport

How do I programatically override the formatter of a Ruport data table?


I have a pretty straight-forward Ruport setup in my Rails app, where the Ruport controller is passed a Report::Data::Table instance:

class Reporter < Ruport::Controller
  stage :headline, :data, :footer
  required_option :report

def setup
    report_klass = options.report.report_model
    report_klass ||= Report
    self.data = report_klass.send(:report_table_by_sql, options.report.query)
  end
end

The Data::Table instance that is stored in data uses Ruport::Data::Table as its delegated controller when asked to render, so that's what gets called when I later call

output << data.to_html

How can I tell data to delegate its rendering methods to the Reporter class, so all my hook overrides can live in one place?


Solution

  • Ruport's API documentation makes it clear that you can register a single Formatter descendant with multiple Controllers, so if you want to have a single formatter that implements all the hooks, you can simply say as much:

    class DualPurposeFormatter < Ruport::Formatter::HTML
      renders :html, :for => [Reporter, Ruport::Controller::Table]
    
      #for Reporter controller
      def build_headline
        #...
      end
    
      #for Ruport::Controller::Table
      def build_row(row_data)
        #...
      end
    end