jyanks
jyanks

Reputation: 2396

More Dynamic Routes?

I have this site where I want to be able to export all the data using CSV. There is a controller called "dataexport" and it has a method for each model. In my routes.rb file, I have this:

match "export_checkouts", :to => "dataexport/checkouts_csv"
match "export_committees", :to => "dataexport/committees_csv"
match "export_libitems", :to => "dataexport/libitems_csv"  
match "export_locations", :to => "dataexport/locations_csv"
match "export_logs", :to => "dataexport/logs_csv"
match "export_patrons", :to => "dataexport/patrons_csv"
match "export_products", :to => "dataexport/products_csv"
match "export_questions", :to => "dataexport/questions_csv"
match "export_reasons", :to => "dataexport/reasons_csv"
match "export_roles", :to => "dataexport/roles_csv"
match "export_sales", :to => "dataexport/sales_csv"
match "export_shifts", :to => "dataexport/shifts_csv"
match "export_tasks", :to => "dataexport/tasks_csv"
match "export_tickets", :to => "dataexport/tickets_csv"
match "export_types", :to => "dataexport/types_csv"
match "export_users", :to => "dataexport/users_csv"
match "export_visitors", :to => "dataexport/visitors_csv"
match "export_years", :to => "dataexport/years_csv"

Is there a more dynamic way of doing this? This definitely goes against the "DRY" paradigm and was wondering if anyone could help me with this. I was thinking that you could just do this in one line by replacing the model names with a variable but I'm not quite sure how to go about doing this.

Upvotes: 1

Views: 92

Answers (2)

Rupert Madden-Abbott
Rupert Madden-Abbott

Reputation: 13278

You could try this:

%w(checkouts committees).each do |model|
  match "export_#{model}", :to => "dataexport/#{model}_csv"
end

Obviously fill out the array with all of the models you need this for.

However, whilst this cuts down on the code, you are still polluting your routes. You should consider that there might be a more Rails-way of doing this.

One thing Rails has support for is responding to different formats in controllers. So if a JSON format is requested by the browser, a JSON file is provided for by Rails (as long as you write the code for it). It sounds to me like you could just do the same thing with a CSV format.

What you are defining as "export" is really just the index method on a normal controller. It's just that rather than displaying the data as HTML, you are displaying it as CSV. I haven't really looked into this myself and so I'm not sure exactly how you would go about doing it. Something like this:

class FooController < ApplicationController
  def index
    respond_to do |format|
      format.html #This will load your standard html index view
      format.csv { #CSV stuff goes here. Perhaps you can get it to load app/views/foo/index.csv.erb somehow }
  end
end

There is some discussion on this here: http://weblog.rubyonrails.org/2006/12/19/using-custom-mime-types

Upvotes: 1

Reuben Mallaby
Reuben Mallaby

Reputation: 5763

Why not just:

match "export/:model", :to => "dataexport/export_csv"

and use params[:model] to get the correct Model, then direct the dataexport controller export_csv method to ask the model for the data in CSV format like:

class DataexportController do
  def export_csv
    params[:model].constantize.export_csv
  end
end

Upvotes: 2

Related Questions