Export A Record To CSV - ruby-on-rails-3

I have a Posts table in my Rails 3.0.10 app. I want to give my users the option to export a particular Post record to CSV format, not all of them. And while my Post table has a lot of fields, I only want to export the title and the body.
After doing some searching apparently the best way to do this is through FasterCSV. And apparently it's already built in Ruby 1.9.2, which I'm using. Thing is pretty much all the tutorials are outdated (from Rails 1 or 2) and I have absolutely no idea how to accomplish this.
I've tried putting in my posts_controller.rb
def export_to_csv
#post = Post.find(params[:id])
csv_string = CSV.generate do |csv|
csv << [#post.title, #post.body]
end
# send it to the browsah
send_data csv_string,
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment; filename=post.csv"
end
Which I THINK may be the right code, but I have no idea how to use it in my view. Ideally I want to have a link to export the CSV file, but I'm thinking it has to be done through a form_tag?
Would appreciate if someone could point me towards the right direction. Thanks.

After several hours of Googling and experimentation I found the answer.
1.) Install this gem: https://github.com/dasil003/csv_builder
2.) Add respond_to do |format| format.csv to the action you want to turn into a CSV (in my case, the def show part of the posts_controller
3.) Create a action.csv.csvbuilder file (in my case, show.csv.csvbuilder) and add the data you need (in my case, add csv << [#post.title, #post.body])
4.) Add a link to the CSV in the views.

Related

How do I retrieve a random GET request in Ruby on Rails 5?

I've created my REST API based on Michael Scott from the Office, so far if you go onto the main part of the API it displays all the quotes /api/v1/quotes/ and you can get individual ones if you add an id number such as /api/v1/quotes/5,but I want users to be able to get a random quote when they put in a GET request.
This would preferably be done with an extra part of the URL such as /api/v1/quotes/random.
I've looked at a lot online but I can't figure this out. Do I put my code into the quotes controller and create another function or do I have to put this somewhere else such as routes.db? Also do I put in the SQL function of RANDOM or is there a better and more efficient way to randomise it. My database only has 50 records in it and it's done in mysql2.
Thanks in advance.
It's my first time posting here as usually I hate asking for help as I think I can always figure it out myself but I'm extremely new to Ruby so I'm fairly clueless on how to solve this. If you need me to clarify my question then just let me know.
You can do that in Model as well as controller.
Model:
class Model < ApplicationRecord
def self.random
Model.limit(1).order("RANDOM()").first
end
end
Controller: In method show
def show
render json: Model.find_by(id: params[:id]) || Model.random
end
I hope that helpful.
I would configure a quotes/random collection route:
# in config/routes.rb
resources :quote do
get 'random', on: :collection
end
and use a controller method like this:
# in controllers/quotes_controller.rb
def random
#quote = Quote.order('RAND()').first
render :show
end
Please note: Returning a single random row from a table is database specific – for MySQL
ORDER BY RAND() LIMIT 1
seems to be the way to go.

Generate rtf document in Rails 3.2

I'm a rails newbie. Could someone tell me if there is a quick and easy way to generate rtf documents for people to download using rails?
For example if I have "views/users/show.html.erb" the view normally outputs to html so I want to people to be able to download as an identical rtf document?
ruby-rtf is the gem you are looking for. There are some examples of rtf generation here
Add this to initializers/mime_types.rb:
Mime::Type.register "text/richtext", :rtf
Code to give you an idea:
document = RTF::Document.new(RTF::Font.new(RTF::Font::ROMAN, 'Times New Roman'))
document.paragraph do |p|
p << "This is the first sentence in the paragraph. "
p << "This is the second sentence in the paragraph. "
p << "And this is the third sentence in the paragraph."
end
send_file document, :type=>"text/richtext"
ruby-rtf - is rtf parsing
this one is for rtf generating - https://github.com/clbustos/rtf
I am doing this on Rails 4.2 and it seems to work so far. I have not tested this on the latest version of Rails but that is next. The gem has not been maintained recently so the verdict is still out on whether or not this will meet all my requirments.
First, Nazar is correct the link should be https://github.com/clbustos/rtf in order to create RTF files from a Rails controller vs parsing RTF files.
I tried the code provided in the answers but an issue exists with using send_file in this implementation. Since send_file is meant for sending a file given a path it doesn't work as shown. On the other hand send_data is used to send a data stream directly from the Rails app. So here is the code I used for creating an RTF document for download from the controller directly.
Basic Setup:
Gemfile:
gem 'rtf'
Install the gem.
config/initializers/mime_types.rb
Mime::Type.register "text/richtext", :rtf
In the "lib" Directory I created a special RTF generator (Putting the code in the controller is fine to generate an RTF document for testing but the RTF generation should be in a seperate file because code to create an RTF document can get long quickly and doesn't really belong in the controller):
lib/rtf_reporting.rb
class RtfReporting
require 'rtf'
def initialize
end
...
def self.get_rtf_document(reporting)
document = RTF::Document.new(RTF::Font.new(RTF::Font::ROMAN, 'Times New Roman'))
document.paragraph do |p|
p << "This is the first sentence in the paragraph. TESTING ID = #{reporting.id}"
p << "This is the second sentence in the paragraph. "
p << "And this is the third sentence in the paragraph."
end
return document.to_rtf
end
end
Controller:
app/controllers/reportings_controller.rb
class ReportingsController < ApplicationController
require 'rtf_reporting'
...
def show
...
respond_to do |format|
format.rtf do
send_data RtfReporting.get_rtf_document(#reporting), :type=>"text/richtext",
:filename => "your_file_name.rtf",
:disposition => 'attachment'
end
end
end
end
I hope this helps someone. The original answers in this post helped me out! In know the biggest difference between my answer and the other answers is send_file vs send_data which in its own right is a big deal but I also wanted to provide some insight on how I would organize my code given that there is no view file like there is for an HTML or PDF based solution.

Creating Custom Post Method

I'm trying to create a a custom post method but i'm having trouble finding how to start.
What I want to do is to be able to read a CSV file, foreach entry, insert a new row into a database.
In the index file, I want to be able to hit 1 link or button to start a custom method.
This method would open my csv file (traverse each row and insert into database)
So essentially on my index.html.erb I would like to see something like:
<%= link_to "Load CSV to Database", :controller => MyController, :action => MyCustomAction %>
I believe I need to edit my routes.rb and this is where I'm stuck. How do I make it so that my routes know that MyCustomAction is a post.
My Rake Route:
use_database_csv_files POST /csv_files/use_database(.:format) csv_files#use_database
csv_files GET /csv_files(.:format) csv_files#index
POST /csv_files(.:format) csv_files#create
new_csv_file GET /csv_files/new(.:format) csv_files#new
edit_csv_file GET /csv_files/:id/edit(.:format) csv_files#edit
csv_file GET /csv_files/:id(.:format) csv_files#show
PUT /csv_files/:id(.:format) csv_files#update
DELETE /csv_files/:id(.:format) csv_files#destroy
Thanks
You can try:
resources :MyController do
collection do
post 'MyCustomAction'
end
end
This blog post may also help you if you want to do member instead of collection

Paperclip not saving files with save()

I have a little problem with paperclip saving the data passed through the form...
If I'm trying to save the record with .save() it won't save.. When I look in the server/log there are no errors or warnings for the paperclip gem :-/
# trying to save the record with save() -- not working :-/
def create
#baan_import = BaanImport.new(params[:baan_import])
if #baan_import.save
redirect_to(baan_imports_url)
else
render 'new'
end
end
Server-log: (using .save() in controller)
https://gist.github.com/1327347
I just don't get it why it's working if I'm using .create instead of .save()
# trying to save the record with Model.create() -- working!
def create
#baan_import = BaanImport.create(params[:baan_import])
redirect_to(baan_imports_url)
end
Server-log: (using .create() in controller)
https://gist.github.com/1327359
Can some one explain me why it's working with create and not with save??
Thanks,
Michael
Can you show us the BaanImport model. My first guess is you're possibly missing baan_upload in attr_accessible on your model, and as a result, Rails will not let you mass assign the file parameter for upload.
Can you also confirm (would appear as though it's properly set up) that your form has html => {:multipart => true} as an option?

multiple image upload with dragonfly

i was trying for multiple image upload with dragonfly in rails3. i searched for some tutorials, but couldn't find any. i found a tutorial for multiple image upload with Carrierwave, but couldnt find luck with dragonfly .. any help please :)
Preface
Dragonfly itself can be used to manage media for your project in general, similar to paperclip. The question itself boils down to the multiple file upload within a rails application. The some tutorials on this topic available, which can easily be adapted to models using Dragonfly for storing specific files on them. I would suggest you look into those and try to adapt them for your project.
However, I can present a minimum example which i built for a rails 3.2 app currently in development, which isn't perfect (validation handling for example), but can give you some starting points.
Example
Just for reference, the essential idea is taken from here. This example is done with Rails 3.2.x.
Let's say you have a vacation database, where users may create trip reports on vacations they took. They may leave a small description, as well as some pictures.
Start out by building a simple ActiveRecord based model for the trips, lets just call it Trip for now:
class Trip < ActiveRecord::Base
has_many :trip_images
attr_accessible :description, :trip_images
end
As you can see, the model has trip images attached to it via a has_many association. Lets have a quick look at the TripImage model, which uses dragonfly for having the file stored in the content field:
class TripImage < ActiveRecord::Base
attr_accessible :content, :trip_id
belongs_to :trip_id
image_accessor :content
end
The trip image it self stores the file attachment. You may place any restrains within this model, e.g. file size or mime type.
Let's create a TripController which has a new and create action (you can generate this via scaffolding if you like, it is by far nothing fancy):
class TripController < ApplicationController
def new
#trip = Trip.new
end
def create
#trip = Trip.new(params[:template])
#create the images from the params
unless params[:images].nil?
params[:images].each do |image|
#trip.trip_images << TripImages.create(:content => image)
end
if #trip.save
[...]
end
end
Nothing special here, with the exception of creating the images from another entry than the params hash. this makes sense when looking at the the file upload field within the new.html.erb template file (or in the partial you use for the fields on the Trip model):
[...]
<%= f.file_field :trip_images, :name => 'images[]', :multiple => true %>
[...]
This should work for the moment, however, there are no limitations for the images on this right now. You can restrict the number of images on the server side via a custom validator on the Trip model:
class Trip < ActiveRecord::Base
has_many :trip_images
attr_accessible :description, :trip_images
validate :image_count_in_bounds, :on => :create
protected
def image_count_in_bounds
return if trip_images.blank?
errors.add("Only 10 images are allowed!") if trip_images.length > 10
end
end
I leave this up to you, but you could also use client side validations on the file field, the general idea would be to check the files upon changing the file field (in CoffeeScript):
jQuery ->
$('#file_field_id').change () ->
#disable the form
for file in this.files
#check each file
#enable the form
Summary
You can build a lot out of existing tutorials, as dragonfly does not behave that differently to other solutions when it comes to just to uploading files. However, if you'd like something fancier, I'd suggest jQuery Fileupload, as many others have before me.
Anyways, I hope I could provide some insight.