andrewdotnich
andrewdotnich

Reputation: 16794

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?

Upvotes: 1

Views: 300

Answers (2)

andrewdotnich
andrewdotnich

Reputation: 16794

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

Upvotes: 1

Andrew France
Andrew France

Reputation: 4879

Ruport formatters are designed to be encapsulated in a separate class that inherits from Formatter. I believe something similar to this will achieve what you want:

# Inherits all the default build methods from the HTML Formatter
class ReporterTableHTMLFormatter < Ruport::Formatter::HTML
  # Sets this class to render Ruport Tables
  # (Data instead of Controller may also work, the code path is a bit unclear/overloaded)
  renders :html, :for => Ruport::Controller::Table

  # Build table row
  def build_row(data)
    ...
  end
end

Upvotes: 1

Related Questions