I have an object Foo
. Foo
has a controller, and the controller has a standard index that displays all Foo
s in a table containing each Foo
's attributes and allows users to filter and sort Foo
s by those attributes. This part works just dandy.
class FoosController < ApplicationController
def index
@foos = Foo.filter_data_by_params
@foos = Foo.sort_some_data_by_params
respond_to do |format|
format.html { standard_index } # Has link to format xls
format.xls do
require_relative '../path/to/spreadsheet_view.rb' # Uh oh.
create_spreadsheet # method in spreadsheet_view that generates and returns xls file
end
end
end
end
But there's another part of this that seems dangerous to me. The index view also provides users the option to view the gathered index data as a spreadsheet. However, because trying to use XLS ERB returns an XML 2004 file rather than a 97-2004 file compatible with our company's workflow, I have to invoke a regular .rb
file that uses the Spreadsheet gem to generate the 97-2004 compatible spreadsheet rather than a .erb
file.
def create_spreadsheet
book = Spreadsheet::Workbook.new
sheet = book.create_worksheet(:name => 'Sheet1')
fields = Foo.columns
sheet.row(0).concat(fields)
@foos.each_with_index do |foo, index|
fields.each do |field|
sheet.row(index + 1).push foo.field
end
end
spreadsheet = StringIO.new
book.write spreadsheet
send_data spreadsheet.string, :filename => "foos.xls", :type => "application/vnd.ms-excel"
end
Now, I'm not sure if using an external .rb
file rather than an .erb
file is necessarily so bad in and of itself, but I do realize that require_relative
is probably a terrible way to go about doing it.
Correct me if I'm wrong, but from what I understand, require_relative
can only be used once per Rails session (as with any Ruby require
) and would define the "create spreadsheet" method on the scope of the entire application rather than for just the current instance of the FoosController
I'm working with.
tl;dr: What I need is a way to expose a method to FoosController#index
that can use the @foos
variable populated by index
to generate a spreadsheet, much like a view file would, without screwing everything else up - i.e. it can be edited without having to reload the server and won't pollute the rest of my app.