Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Is it possible to pass my own arguments into the constructor for a report? #54

Open
PRAgarawal opened this issue Mar 25, 2015 · 4 comments

Comments

@PRAgarawal
Copy link

In my ApplicationController, I have a generic index action [that can be overridden by any controller] where I want to return the CSV for any object with something like this:

def index
  @records = apply_page_query_parameters(policy_scope(resource_class))
  respond_to do |format|
    format.html { render_records(@records) }
    format.csv {
      report = GenericReport.new(project: @all_records, table: resource_class)
      send_data generate_csv_from_report(report.results)
    }
  end
end

But I can't seem to figure out how to pass in that table parameter, which I'd like to use in a GenericReport class kind of like this:

class GenericReport < Dossier::Report
  def sql
    'SELECT * FROM table <= :table'
  end
end

Would appreciate some help! And while I'm here, is there a way to generate the CSV from a report object directly? I wrote the generate_csv_from_report function myself in a helper I created. It was a very small and simple method, but it would be nice to eliminate it entirely.

For the record, the reason I do this instead of redirecting to the dossier reports route is that it was far easier to authorize access to a report this way when using the pundit gem.

@sufleR
Copy link

sufleR commented Jun 25, 2015

If you are not afraid of sql injection do something like

def sql
"SELECT * FROM #{ options[:table] }"
end

and in controller pass table as

report = GenericReport.new(project: @all_records, table: resource_class.table_name)

@kcollignon
Copy link

@RocketGuy3 were you ever able to figure this out?

@JeremiahChurch
Copy link

@kcollignon - I just ran in to a similar issue myself.

I needed tenancy - something that can't just be passed via a URL param. As the reports themselves don't have session info I ended up monkey patching the reports controller to add it to the options param hash that gets sent to the report

# /config/initializers/dossier.rb
# Overridding options_params in Dossier controller to add tenancy support

module Dossier
  class ReportsController < ApplicationController
    include ViewContextWithReportFormatter

    self.responder = Dossier::Responder

    respond_to :html, :json, :csv, :xls

    def show
      respond_with(report)
    end

    def multi
      respond_with(report)
    end

    private

    def report_class
      Dossier::Model.name_to_class(params[:report])
    end

    def report
      @report ||= report_class.new(options_params)
    end

    def options_params
      # original was: params[:options].presence || {}
      if params[:options].present?
        params[:options].merge(company_id: current_user.company_id)
      else
        {}.merge(company_id: current_user.company_id)
      end
    end
  end
end

then in my reports I have

  def company_id
    options[:company_id]
  end

and the sql strings for the reports can use ':company_id' as needed in where & join clauses.

It's a fast hack that Ill revisit after I put the fire out but it's working. Hopefully it's of some help to you or others. I'm interested in how others are solving this problem as well.

@PRAgarawal
Copy link
Author

I was never able to get it working, so I had to abandon the gem and write my own solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants