Giter Site home page Giter Site logo

dossier's Introduction

Dossier

Dossier is a Rails engine that turns SQL into reports. Reports can be easily rendered in various formats, like HTML, CSV, XLS, and JSON.

  • If you hate SQL, you can use whatever tool you like to generate it; for example, ActiveRecord's to_sql.
  • If you love SQL, you can use every feature your database supports.

Gem Version Code Climate Build Status Coverage Status Dependency Status

Setup

Install the Dossier gem and create config/dossier.yml. This has the same format as Rails' database.yml, and can actually just be a symlink (from your Rails.root: ln -s database.yml config/dossier.yml).

Routing

Dossier will add a route to your app so that reports/fancy_ketchup will instantiate and run a FancyKetchupReport. It will respond with whatever format was requested; for example reports/fancy_ketchup.csv will render the results as CSV.

Formats

Dossier currently supports outputting to the following formats:

  • HTML
  • CSV
  • XLS
  • JSON

Any of these formats can be requested by using the appropriate format extension on the end of the report's URL.

Basic Reports

In your app, create report classes under app/reports, with Report as the end of the class name. Define a sql method that returns the sql string to be sent to the database.

For example:

# app/reports/fancy_ketchup_report.rb
class FancyKetchupReport < Dossier::Report
  def sql
    'SELECT * FROM ketchups WHERE fancy = true'
  end

  # Or, if you're using ActiveRecord and hate writing SQL:
  def sql
    Ketchup.where(fancy: true).to_sql
  end

end

If you need dynamic values that may be influenced by the user, do not interpolate them directly. Dossier provides a safer way to add them: any lowercase symbols in the query will be replaced by calling methods of the same name in the report. Return values will be escaped by the database connection. Arrays will have all of their contents escaped, joined with a "," and wrapped in parentheses.

# app/reports/fancy_ketchup_report.rb
class FancyKetchupReport < Dossier::Report
  def sql
    "SELECT * FROM ketchups WHERE price <= :max_price and brand IN :brands"
    # => "SELECT * FROM ketchups WHERE price <= 7 and brand IN ('Acme', 'Generic', 'SoylentRed')"
  end

  def max_price
    7
  end

  def brands
    %w[Acme Generic SoylentRed]
  end
end

Header Formatting

By default, headers are generated by calling titleize on the column name from the result set. To override this, define a format_header method in your report that returns what you want. For example:

class ProductMarginReport < Dossier::Report
  # ...
  def format_header(column_name)
    custom_headers = {
      margin_percentage: 'Margin %',
      absolute_margin:   'Margin $'
    }
    custom_headers.fetch(column_name.to_sym) { super }
  end
end

Column Formatting

You can format any values in your results by defining a format_ method for that column on your report class. For instance, to reverse the names of your employees:

class EmployeeReport < Dossier::Report
  # ...
  def format_name(value)
    value.reverse
  end
end

Dossier also provides a formatter with access to all the standard Rails formatters. So to format all values in the payment column as currency, you could do:

class MoneyLaunderingReport < Dossier::Report
  #...
  def format_payment(value)
    formatter.number_to_currency(value)
  end
end

In addition, the formatter provides Rails' URL helpers for use in your reports. For example, in a report of your least profitable accounts, you might want to add a link to change the salesperson assigned to that account.

class LeastProfitableAccountsReport < Dossier::Report
  #...
  def format_account_id(value)
    formatter.url_formatter.link_to value, formatter.url_formatter.url_helpers.edit_accounts_path(value)
  end
end

The built-in ReportsController uses this formatting when rendering the HTML and JSON representations, but not when rendering the CSV or XLS.

If your formatting method takes a second argment, it will be given a hash of the values in the row.

class MoneyLaunderingReport < Dossier::Report
  #...
  def format_payment(value, row)
    return "$0.00" if row[:recipient] == 'Jimmy The Squid'
    formatter.number_to_currency(value)
  end
end

Hidden Columns

You may override display_column? in your report class in order to hide columns from the formatted results. For instance, you might select an employee's ID and name in order to generate a link from their name to their profile page, without actually displaying the ID value itself:

class EmployeeReport < Dossier::Report
  # ...

  def display_column?(name)
    name != 'id'
  end

  def format_name(value, row)
    url = formatter.url_formatter.url_helpers.employee_path(row['id'])
    formatter.url_formatter.link_to(value, url)
  end
end

By default, all selected columns are displayed.

Report Options and Footers

You may want to specify parameters for a report: which columns to show, a range of dates, etc. Dossier supports this via URL parameters, anything in params[:options] will be passed into your report's initialize method and made available via the options reader.

You can pass these options by hardcoding them into a link, or you can allow users to customize a report with a form. For example:

# app/views/dossier/reports/employee.html.haml

= form_for report, as: :options, url: url_for, html: {method: :get} do |f|
  = f.label "Salary greater than:"
  = f.text_field :salary_greater_than
  = f.label "In Division:"
  = f.select_tag :in_division, divisions_collection
  = f.button "Submit"

= render template: 'dossier/reports/show', locals: {report: report}

It's up to you to use these options in generating your SQL query.

However, Dossier does support one URL parameter natively: if you supply a footer parameter with an integer value, the last N rows will be accesible via report.results.footers instead of report.results.body. The built-in show view renders those rows inside an HTML footer. This is an easy way to display a totals row or something similar.

Styling

The default report views use a <table class="dossier report"> for easy CSS styling.

Additional View Customization

To further customize your results view, run the generator provided. The default will provide 'app/views/dossier/reports/show'.

rails generate dossier:views

You may pass a filename as an argument. This example creates 'app/views/dossier/reports/account_tracker.html.haml'.

rails generate dossier:views account_tracker

Callbacks

To produce report results, Dossier builds your query and executes it in separate steps. It uses ActiveSupport::Callbacks to define callbacks for build_query and execute. Therefore, you may provide callbacks similar to these:

set_callback :build_query, :before, :run_my_stored_procedure
set_callback :execute,     :after do
  mangle_results
end

Using Reports Outside of Dossier::ReportsController

With Other Controllers

You can use Dossier reports in your own controllers and views. For example, if you wanted to render two reports on a page with other information, you might do this in a controller:

class ProjectsController < ApplicationController

  def show
    @project                = Project.find(params[:id])
    @project_status_report  = ProjectStatusReport.new(project: @project)
    @project_revenue_report = ProjectRevenueReport.new(project: @project, grouped: 'monthly')
  end
end
.span6
  = render template: 'dossier/reports/show', locals: {report: @project_status_report.run}
.span6
  = render template: 'dossier/reports/show', locals: {report: @project_revenue_report.run}

Dossier for APIs

class Api::ProjectsController < Api::ApplicationController

  def snapshot
    render json: ProjectStatusReport.new(project: @project).results.hashes
  end
end

Advanced Usage

To see a report with all the bells and whistles, check out spec/dummy/app/reports/employee_report.rb or other reports in spec/dummy/app/reports.

Compatibility

Dossier currently supports all databases supported by ActiveRecord; it comes with Dossier::Adapter::ActiveRecord, which uses ActiveRecord connections for escaping and executing queries. However, as the Dossier::Adapter namespace implies, it was written to allow for other connection adapters. See CONTRIBUTING.md if you'd like to add one.

Protecting Access to Reports

You probably want to provide some protection to your reports: require viewers to be logged in, possibly check whether they're allowed to access this particular report, etc.

Of course, you can protect your own controllers' use of Dossier reports however you wish. To protect report access via Dossier::Controller, you can make use of two facts:

  1. Dossier::Controller subclasses ApplicationController
  2. If you use an initializer, you can call methods on Dossier::Controller

So for a very simple, roll-your-own solution, you could do this:

# config/initializers/dossier.rb
Rails.application.config.to_prepare do
  # Define `#my_protection_method` on your ApplicationController
  Dossier::ReportsController.before_filter :my_protection_method
end

For a more robust solution, you might make use of some gems. Here's a solution using Devise for authentication and Authority for authorization:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # Basic "you must be logged in"; will apply to all subclassing controllers,
  # including Dossier::Controller.
  before_filter :authenticate_user!
end

# config/initializers/dossier.rb
Rails.application.config.to_prepare do
  # Use Authority to enforce viewing permissions for this report.
  # You might set the report's `authorizer_name` to 'ReportsAuthorizer', and
  # define that with a `readable_by?(user)` method that suits your needs
  Dossier::ReportsController.authorize_actions_for :report_class
end

See the referenced gems for more documentation on using them.

Running the Tests

Note: when you run the tests, Dossier will make and/or truncate some tables in the dossier_test database.

  • Run bundle
  • RAILS_ENV=test rake db:create
  • cp spec/dummy/config/database.yml{.example,} and edit it so that it can connect to the test database.
  • cp spec/fixtures/db/mysql2.yml{.example,}
  • cp spec/fixtures/db/sqlite3.yml{.example,}
  • rspec spec

Moar Dokumentationz pleaze

  • How Dossier uses ORM adapters to connect to databases, currently only AR's are used.
  • Examples of connecting to different databases, of the same type or a different one
  • Document using hooks and what methods are available in them
  • Callbacks, eg:
    • Stored procedures
    • Reformat results
  • Linking
    • To other reports
    • To other formats
  • Extending the formatter
  • Show how to do "crosstab" reports (preliminary query to determine columns, then build SQL case statements?)

Roadmap

  • Moar Dokumentationz pleaze
  • Use the roo gem to generate a variety of output formats

dossier's People

Contributors

adamhunter avatar bvandgrift avatar hughkelsey avatar jezstephens avatar lwangenheim avatar nathanl avatar rossta avatar rubysolo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dossier's Issues

Securing reports???

Is there a mechanism which can protect reports from being accessed by non-authenitcated users, or even better, some way to control access by CanCan?

For instance, I use Rolify and CanCan to protect certain controller actions from regular authenticated users so they can only be accessed by a User that has the Admin role.

Without a feature like this, it seems that anyone can access any report. Maybe there are other mechanisms that I am just not yet aware of??

Using just the library without using entire engine?

I'd be interested in using just the heavy lifting parts of dossier (the reports model and responder), but I have my own controller/view/route structure, and authentication/authorization logic (e.g. not inheriting at all from ::ApplicationController, and don't want to drag in the all the routes and controllers from dossier (which happens as soon as I load the gem) but would rather use my own.

Is there any support for allowing using just the report builder layer but not full MVC stack of dossier?

Thanks!

undefined method `url_helpers'

I'm getting this error when running a report. It says the url_helpers method is undefined:

NoMethodError at /reports/contacts.
undefined method `url_helpers' for Dossier::Formatter:Module

  def format_id(value)
     if value.is_a?(Integer)
       formatter.link_to value, formatter.url_helpers.edit_contact_path(value)
     else
       value
     end
   end

Can you namespace the default dossier route?

We have an admin console that uses routes starting with 'admin'. All of the admin routes use controllers that inherit from Admin::ApplicationController. This controller has auth logic (ie. ensure_super_user).

Is it possible to configure dossier default route / controller to use a different namespace? In other words, is it possible to configure dossier's automatically created 'report' route so that it is 'admin/report' and those routes use a ReportController derived from Admin::ApplicationController instead?

I tried rolling my own, which more or less works eg:

#routes.rb 
namespace :admin do
  ...
  match 'reports/:action', :controller=>'reports', :as => :reports

class Admin::ReportsController < Admin::ApplicationController

But occasionally things don't work as expected. For instance, the options don't get passed automatically to the report. I fixed by passing params[:options] when I create the report, but it feels like I'm duplicating internal behavior. Is there a better way?

#AdminReport::Controller#referrals_report
    report = ReferralsReport.new(params[:options])
    render template: 'admin/reports/referrals', locals: {report: report.run}

format_header() doesn't seem to work??

I've defined a format_header method in my report class (based on the sample code here on this site), and the resulting sql cursor has the field named "notes", but the report header for that column is not getting overridden with the value I provide in the method:

  def format_header(column_name)
    custom_headers = {
      notes: 'Test'
    }
    custom_headers.fetch(column_name.to_sym) { super }
  end

Am I missing something?

NameError in Dossier::ReportsController#show uninitialized constant

Dossier::ReportsController can't seem to find my report.

Here's the error:
NameError in Dossier::ReportsController#show
uninitialized constant FooReport

Here's my report:
$ cat app/reports/FooReport.rb
class FooReport < Dossier::Reports
def sql
"select 1"
end
end

This is in a brand new Rails project to test this problem.

Rails 3.2.17, ruby 2.0.0p353.

Passing options to Report from Controller

Is it possible to pass options to a report (being used in custom controller)?

Currently it only appears options can be passed via URL parameters. Some of the options I do not want to show in the URL, but rather pass them in via the controller

@report = TimeReport.new(current_user: @user)

Cannot access Result rows or columns.

Whenever I attempt to view a report (any format, but I'll list the errors from attempting to view the HTML format here), I get errors when trying to access anything in the Dossier::Result class related to rows and columns.

However, when I jump into Rails Console, I can create a new report (@rpt for example), run it, data returns as expected, and I can access column names via @rpt.results.adapter_results.result[0].keys.

My hunch is something has gone wrong for me in the lib/Adapter/ActiveRecord/Result.rb but I can't figure out what would be causing it to not see the standard AR methods. Any insight would be appreciated, as this looks like an awesome tool.

Be warned, my configuration might be creating edge cases, so if it's something strange because of that, I won't be surprised. Here's are the relevant lines from my framework trace:

/home/mattgarrison/.rvm/gems/jruby-1.7.2@torquebox-rails/bundler/gems/dossier-6b69abdf44da/lib/dossier/adapter/active_record/result.rb:17:in `rows'
/home/mattgarrison/.rvm/gems/jruby-1.7.2@torquebox-rails/bundler/gems/dossier-6b69abdf44da/lib/dossier/result.rb:47:in `each'
org/jruby/RubyEnumerable.java:383:in `to_a'
/home/mattgarrison/.rvm/gems/jruby-1.7.2@torquebox-rails/bundler/gems/dossier-6b69abdf44da/lib/dossier/result.rb:25:in `rows'
/home/mattgarrison/.rvm/gems/jruby-1.7.2@torquebox-rails/bundler/gems/dossier-6b69abdf44da/lib/dossier/result.rb:17:in `body'
org/jruby/RubyBasicObject.java:1671:in `__send__'

I'm using the current git repo source for Dossier, JRuby 1.7.2, Torquebox 2.3, Rails 3.2.12 and the following ActiveRecord gems: 'activerecord-jdbc-adapter', 'jdbc-mssql-azure', 'activerecord-jdbcmssql-adapter', 'composite_primary_keys'. Dossier is the last gem in my gemfile too.

crosstab example

I've got a number of basic queries working and found the gem to be quite useful.

However, I have the following crosstab query:

class OverflowPivotReport < Dossier::Report
  def sql
    '
    SELECT * FROM crosstab('
        SELECT zip, status, status_count
        FROM "status_counts"
        ORDER BY 1, 2;')
    AS ct (zip character varying, "0" bigint, "1" bigint, "2" bigint, "8" bigint);
    '
  end
end

status_counts is a DB view.
when I run the query directly on the DB it works fine.

I get the following error when I run the .html report:

undefined local variable or method `zip' for #<OverflowPivotReport:0x007fc2dd1cacd0>

I saw the following in the documentation:

Show how to do "crosstab" reports (preliminary query to determine columns, then build SQL case statements?)

Not sure where to go from here...

Does not work with Rails 6

Start up a new rails app

# Note: Not exact

rails _6.0.0.0_ new rails6

# Add dossier to gemfile
bundle install
rails generate scaffold Post name:string title:string content:text

rails c
Post.all

The final command spits out an error: ArgumentError (wrong number of arguments (given 2, expected 1))

Here's a working repo to reproduce the issue. You can swap between rails 6 and rails 5 to see that it is working in 5.
https://github.com/ELepolt/rails6-dossier

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

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.

Gemspec warning when installing with Bundler

I just got this warning when installing with Bundler:

dossier at /Users/nathanlong/.rvm/gems/ruby-1.9.3-p374@athena/bundler/gems/dossier-7a274a849829 did not have a valid gemspec.
This prevents bundler from installing bins or native extensions, but that may not affect its functionality.
The validation message from Rubygems was:
  ["README.markdown"] are not files

MultiTenant App with Dossier

I've been using the dossier gem for a while and I think its a pretty awesome gem. However, when I needed to make my app multi-tenant using apartment, I ran into the problem where I could not switch the schema that dossier is using. Is there a clean way to override this or support this?

Edit -
I just figured out that I could just monkey patch Dossier class with the following code

class Dossier::Report
  def tenant
    Apartment::Tenant.current
  end
end

module Dossier
  class Query
    private
    def compile
      string.gsub(/:tenant/, report.public_send(:tenant)).gsub(/\w*\:[a-z]{1}\w*/) { |match| escape(report.public_send(match[1..-1])) }
    end
  end
end

and then just use :tenant in the sql query itself. Leaving this here for any other poor soul who are having this problem.

Derived data columns

Is there any way to add derived data columns?

Using the ProductMarginReport example, the model doesn't need to store both margin_percentage and absolute_margin because it is easily calculable using a method within the model. However, I don't see how to incorporate such derived or value-added methods as columns in a report. I have a lot of existing models with similar derived data methods.

Listing out all reports

Not enough testing for a pull request but not an issue because I have a solution.

Just sharing.

if you would like to list out all of your reports you can do

@report_names = Pathname.glob('app/reports/*').map{|f| f.basename("_report.rb")}.collect(&:to_s)

then in your view you can use

 <li> <%= link_to report_name.titleize, dossier_report_path( report: report_name ) %> </li>

Rails 4.2 ActionController::Responder Integration

Rails 4.2 removes ActionController::Responder into its own gem (refer responders gem and release notes).

With Rails 4.2, Dossier gives the error uninitialized constant ActionController::Responder

A workaround is to include the new dependency in the client application before the dossier gem, e.g.:

gem "responders"
gem "dossier"

Pagination question

Is it possible to paginate these reports or use the will-paginate gem in conjunction with them? If so, do you have an example of how to do this? Thanks.

JSON/CSV issues with display_column?

The JSON responder has an issue with the #display_column? feature. Headers for hidden columns aren't removed, but the value is, so the columns and values don't match up after the headers and values are zipped into a hash (unless the hidden column is at the end).

CSV, on the other hand, doesn't seem to be hooked into the display_column? logic at all since the responder uses #raw_results.

Connection not working on production

Reports are working fine in development but in production, I get the following error:

ActionView::Template::Error: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?

Any reason why this might be?

Configuration missing error

I just upgraded Rails 4 (4.1.1), and now in production when I try to run a report I get this error:

Dossier::ConfigurationMissingError (No such file or directory - /app/config/dossier.yml

Why is it looking under the app folder? I do not get an error in my development environment.

Report Options and Footers

"You can pass these options by hardcoding them into a link, or you can allow users to customize a report with a form."

Can you provide an example of using it in the URL?

default formatter

It would be nice to have a format_default method that, if defined, can be called to format columns. That may not be the best name as we'll have to avoid naming conflicts with column names.

Incompatible with rails 4.1

When trying to run in rails 4.1 I received the error uninitialized constant AbstractController::Layouts (NameError)

Error in XLS file format???

2013-02-10_22-20-36
2013-02-10_22-18-57
When I call for the XLS format, it downloads a file to my Downloads folder, but when I try to open that file with Excel 2010, I get this error message:

"The file you are trying to open, 'test-report_02-10-2013_22-07-06.xls', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?"

(I'm developing the Rails app on a Mac, but my users will be using Excel on a Windows machine to view this spreadsheet.)

If I click on YES, the file actually does open up just fine, so I guess it's no great issue, however, I can see that this could be very concerning to some users.

I also tried opening the file on my Mac using Libre Office, but I also get an error:
"General Error. General input/output error."

However, Libre Office is not as forgiving as Excel, and it on has an OK button for that error message, and it does not open the file.

How can I select a database column without displaying it as its own report column?

Silly question, but if I knew how to do this once, I've forgotten.

Say I've got this query for a report:

SELECT name, color, id FROM widgets;

I don't want to display the id as its own column; instead, I want the name to link somewhere using that id.

def format_name(value, row)
  # build link using value and row[:id]
end

How can I prevent id from showing up as its own column?

Move "Download CSV" link to top of page???

Would you consider moving the "Download CSV" link to the top of the page? The reason I ask is that the report that I am rendering to the page has a few hundred lines, and if the user never scrolls to the bottom of the page, they will never see the "Download CSV" link, and they may not even know that they can download the file.

I've attached a screenshot showing the proposed layout. I also added a horizontal line which makes a nice visual separation between this link and the column headers.

Also, once Excel exporting is working, might you also add a "Download XLS" link as well?

2013-02-11_23-20-39

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

CSV Report Formatting

I was exporting a report to CSV and noticed that only the headers are formatted properly. Any formatting done on the rest of the data is ignored. Is there any particular reason for this or should I create a pull request to change it?

Feature: Validation

What is the recommended way to handle invalid input (i.e., options)? Reports are kinda like models, but they don't have validation. Maybe it would be good if they did. Otherwise, what I can do when report receives bad options except raise an error, which is pretty ugly for the user?

Grouped information

How can I show grouped information in my report? I have the following sql:

SELECT team, player_name from players

And I want to show my report like this:

Team 1
Player 1
Player 2

Team 2
Player 1
Player 2

Custom Layout

Is there a way to use a custom layout for views? My intent is to link a custom stylesheet. Maybe there is another way to do that and otherwise add things to the document head?

What commands are needed to get this up and running?

Are there any commands that need to be run such as rails g dossier to get things up and running? I've been creating all of the files by hand and I have a feeling that's not the way things are supposed to be done.

Also, is it required to use HAML? I'm more comfortable with ERB.

(Still new to rails in case you couldn't tell.)

Return more than one query to report

Wondering if there's a simple way to display more than one query results in different parts of the report. Imagine the top of the report is some rows and columns with numbers, and the bottom is a few text fields with information the report filler added. It seems messy to return it all in one query, but I can do it whatever way works.

format_header doesn't seem to work with spreadsheets

First off, thanks a bunch for dossier, it's working really well for me to get a report framework up and running quickly.

Overriding format_header doesn't seem to change behavior when downloading the .csv or .xls spreadsheets. My format_header has a fail in it but no exception is thrown. When I've tried without the fail my implemented behavior isn't followed.

I think the problem is in lib/dossier/stream_csv.rb and lib/dossier/xls.rb where Dossier::Formatter.titleize is called instead of report.format_header.

How to specify which view to use?

I'm having trouble finding out how to get dossier to render app/views/dossier/reports/some_report.html.haml instead of the show.html.haml.

I have SomeReport class that i want to be render using some_report.html.haml.

Feature request: select values without displaying them

It would be useful to be able to select values without displaying them.

For example, in a user productivity report, I may want to link to the users. To build a link from the user's name to their profile, I need to select the user's ID. This makes it available in the row so that the name column's formatter can use it to build a link_to.

However, it's not actually useful to display the user ID in the report; the user's name and link is sufficient.

Question: Is there a correct way to add a total or summary row?

Hello,

I'm trying to add a total row by adding up values from the results, something like this in my class

  def results
    original_results = super
    total_value = original_results.rows.map {|row| row.last.to_f}.sum.round(2)
    original_results.rows << ['Total', total_value.to_s]
    original_results
  end

This somewhat works however now my report has 2 additional rows:

Total 4546.1
Total 9092.2

The first one is correct, the second is exactly double. Is there a recommended way of adding a total or summary row? Thanks for the help.

Using with other controllers

Hi,
if I create a sample create which integrates some reports I get always this erro message:

order by EXTRACT(YEAR_MONTH FROM te.tracedate) ASC;
Rendered ---/.rbenv/versions/1.9.3-p125/lib/ruby/gems/1.9.1/gems/dossier-2.1.1/app/views/dossier/reports/show.html.haml (7.1ms)
Rendered reporting/show.html.erb within layouts/application (459.7ms)
Completed 500 Internal Server Error in 462ms

ActionController::RoutingError (No route matches {:controller=>"dossier/reports", :action=>"show", :format=>"csv", :options=>nil}):
app/views/reporting/show.html.erb:1:in `_app_views_reporting_show_html_erb__2701691626748388068_70208727835160'

But if I delete the last line in dossier-2.1.1/app/views/dossier/reports/show.html.haml which is:
link_to 'Download CSV', dossier_report_path(:format => 'csv', :options => params[:options]), :class => 'download-csv'

everything is working ok.

Did I miss something?

Greetings
Alex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.