Using url variables in dossier reporting gem

707 views Asked by At

I'm trying out the dossier gem for reporting.
https://github.com/adamhunter/dossier

Can't seem to find in any of the docs how to send over a url variable like reports/test.csv?id=1

Have tried a few things, either get errors or blank values.

2

There are 2 answers

1
Adam On BEST ANSWER

This answer probably comes a bit too late but I thought I'd share for future googlers.

tl;dr

/report/test?options[p1]=v1&options[p2]=v2 will be available inside the TestReport instance as options[:p1] # => 'v1' and options[:p2] # => 'v2'

Explanation:

When visiting a url such as /reports/test.csv you will trigger TestReport to be instantiated and ultimately receive CSV output. If you would like to pass dynamic options in from the URL you would add them to the :options parameter which will be passed by the controller to the instantiated report.

All that is to say in the url use a format such as: /reports/test.csv?options[id]=1&options[so_fancy]=true. This will cause TestReport.new(id: '1', so_fancy: 'true') to be called in the controller. Inside of the report instance you will be able to access these options via the options hash. I personally usually write accessors for my options because this allows me to handle typecasting. All options come in as strings (because all controller parameters come in a strings).

For example:

class TestReport < Dossier::Report
  # NEVER interpolate options directly into your query
  # This uses id_where which will trigger query binding via the :id reference
  # your column names do not need to map to your options
  def sql
    "select * from foos where #{id_where} fancification = :fancy"
  end

  # conditionally adding this clause if id is present in options
  def id_where
    "id = :id or" if options[:id].present?
  end

  # makin' sure id is a number, probably superfluous, mainly for example
  def id
    options[:id].to_i
  end

  # the getter method names and the options keys do not need to correspond, 
  # don't forget all values come in a strings!
  def fancy
    options[:so_fancy] == 'true' ? true : false
  end
end

Hopefully this answers your question!

0
Jackie Johnston On

Your URL will need to look something like:

http://www.example.com/reports/test?options[id]=1

and you'll add a method with the same name as your option, in this case id to your report in order to capture that URL parameter:

class TestReport < Dossier::Report

  def sql
    "SELECT * FROM foos WHERE id = :id"
  end

  def id
    options[:id]
  end

end