Ransack export results to CSV - ruby-on-rails

I'm trying to export a list of Ransack (Railscast) results to a CSV file (Railcast). However, it keeps exporting all of the objects, instead of the results returned by the Ransack search. Can anyone tell me where I'm going wrong?
In the Reports controller, I've tried passing both #bookings and #search.result:
def index
#search = current_user.bookings.search(params[:q])
#bookings = #search.result
#search.build_condition
respond_to do |format|
format.html
format.csv { render text: Booking.to_csv(#bookings) }\
end
end
And then the Booking to_csv method:
def self.to_csv list
CSV.generate do |csv|
csv << column_names
list.each do |booking|
csv << booking.attributes.values_at(*column_names)
end
end
end
Yet every time, I get the unfiltered list of current_user.bookings. Why?

To export only the filtered results as csv, you should make sure that the search parameters are included in the url you call to generate the csv.
Hence, if you want to export the results that you see on the html page you should call:
reports_path(params.merge(format: 'csv')

Try this:
def index
session[:q] = params[:q] if params[:q]
#search = current_user.bookings.search(session[:q])
#bookings = #search.result
#search.build_condition
respond_to do |format|
format.html
format.csv { render text: Booking.to_csv(#bookings) }\
end
end

Related

Rails export to CSV file

It is partly working. It generates the file but the output is not how I want it.
Controller
#messages = Message.take(2)
respond_to do |format|
format.html
format.csv { send_data #messages.to_csv }
end
Message.rb
def self.to_csv
CSV.generate do |csv|
csv << Message.attribute_names
Message.all.each do |message|
csv << message.attributes.values
end
end
end
I get the CSV file downloaded, it contains the records itself but it does not show the columns and values
#<Message:0x007fca7a028338>,#<Message:0x007fca79a6bf58>
I would expect the Message attributes like:
ID,text
1,hello
2,world
Message.take(2) returns Array. You need ActiveRecord::Relation.
Try Message.limit(2)

Why rails download csv file when I want to show html using render :text or html?

It's simple..
when I write it in my controller like this.
def index
#articles = News.order(:id)
respond_to do |format|
format.html
format.csv { render text: #articles.to_csv}
end
end
and in news.rb
def self.to_csv
CSV.generate do |csv|
csv << column_names
all.each do |product|
csv << product.attributes.values_at(*column_names)
end
end
end
What I expected when I open my site(http://localhost:3000/mycontroller.csv) is shows the text in my screen.
However, it just download csvfile..... Even when I changed render text to html.
What is wrong in my code?
You can try this code
class HomeController < ApplicationController
respond_to :html, :json, :csv
def index
#modelnames = Modelname.all
respond_with(#modelnames)
end
end

Rails Exporting CSV ignore blanks

I'm trying to create a simple CSV export in Rails. The export works fine except when deleting/archiving table items. I'm guessing this is because the export is encountering blanks.
This is working:
= link_to transactions_path(format: :csv) do
Except when there is a item missing from the transaction.
Tried this
= link_to transactions_path(format: :csv,skip_blanks: true) do
but I still get a ERR_INVALID_RESPONSE when calling the export
TransactionController:
respond_to :html, :json, :csv
def index
#shops = current_user.shops
respond_with(#shops) do |format|
format.csv do
response.headers['Content-Type'] = 'text/csv'
response.headers['Content-Disposition'] = "attachment; filename=transactions-#{Time.now.strftime('%Y%m%d%H%M')}.csv"
render inline: #shops.to_csv
end
end
end
Any suggestions?
Change to_csv to pass skip_blanks.
#shops.to_csv(skip_blanks: true)
If you want a link to download a CSV file, you should use send_data instead. If you want to display the file in the browser, use render text: #shops.to_csv
http://railscasts.com/episodes/362-exporting-csv-and-excel
respond_to :html, :json, :csv
def index
#shops = current_user.shops
respond_with(#shops) do |format|
format.csv do
send_data #shops.to_csv, type:'text/csv', filename: "transactions-#{Time.now.strftime('%Y%m%d%H%M')}.csv"
end
end
end
Change your link_to back to what you had before.
= link_to transactions_path(format: :csv)
Maybe using send_data:
def index
respond_to do |format|
format.csv { send_data #current_user.shops.to_csv, filename: "transactions-#{Time.now.strftime('%Y%m%d%H%M')}.csv" }
end
end
Also, is the to_csv an instance method?

Why is Rails exporting all rows instead of only filtered results?

I'm running a Rails 4 application and am using the Ransack gem to filter results for employees. I've seen multiple examples of how to limit columns on the exported CSV file, but not on limiting rows. To my understanding, the following code should call the .to_csv method on the filtered employees, but currently all rows are being downloaded. Do I need to pass an array of the IDs of the filtered results to the .to_csv method?
View:
<h3>Download</h3>
<%= link_to "CSV", employees_path(format: "csv") %>
Controller:
def index
#q = Employee.ransack(params[:q])
#q.build_condition
#employees = #q.result(distinct: true)
respond_to do |format|
format.html
format.csv { render text: #employees.to_csv }
end
end
Model:
def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |employee|
csv << employee.attributes.values_at(*column_names)
end
end
end
I know this is a bit delayed but this is how I fixed same problem.
Change the link to have params.merge to keep the filtered results.
<%= link_to "CSV", employees_path(params.merge(format: "csv")) %>
I also had to change my format.csv to the following to get it to work:
format.csv { send_data #employees.to_csv, filename: "employees.csv" }
Hope this helps.
In this line you're adding all of the employee models.
all.each do |employee|
Instead you should have something like
def self.to_csv(employees)
..
employees.each do |employee|
..
end
And call this class method like this:
format.csv { render text: Employee.to_csv(#employees) }
(Read more about class methods here)

Rails 4 download to CSV

I'm building a marketplace app so sellers can list items to sell. I'm trying to download a CSV by seller so sellers can download their own listings.
I'm following the code in this railscast. I got the railscasts code to work as-is. It downloads all the data from my model into a csv. But when I add a seller filter to the query, it doesn't apply the filter.
In listings_controller:
def index
#listings = Listing.not_expired.order("created_at DESC")
respond_to do |format|
format.html
format.csv { send_data #listings.to_csv }
end
end
def seller
#listings = Listing.where(user: current_user).order("created_at DESC")
respond_to do |format|
format.html
format.csv { send_data #listings.seller_csv }
end
end
in listing.rb:
def self.to_csv
CSV.generate do |csv|
csv << column_names
all.each do |listing|
csv << listing.attributes.values_at(*column_names)
end
end
end
def self.seller_csv
CSV.generate do |csv|
csv << column_names
where(user: current_user).each do |listing|
csv << listing.attributes.values_at(*column_names)
end
end
end
The to_csv methods works fine and downloads all listings. But the seller_csv method also downloads all listings. I need it to filter by current_user. What am I missing?
Make your function take a list of listings as parameter.
def self.to_csv(listings)
CSV.generate do |csv|
csv << column_names
listings.each do |listing|
csv << listing.attributes.values_at(*column_names)
end
end
end
Then you cane re-use the same function in the two scenarios
def index
#listings = Listing.not_expired.order("created_at DESC")
respond_to do |format|
format.html
format.csv { send_data Listing.to_csv(#listings) }
end
end
def seller
#listings = Listing.where(user: current_user).order("created_at DESC")
respond_to do |format|
format.html
format.csv { send_data Listing.to_csv(#listings) }
end
end
Your code didn't make really sense as you were fetching listings in your controller but never re-used those fetched objects and was re-calling DB in your model's static functions.

Resources