How to convert html table to PDF using Rails 3 - ruby

I am trying to generate one PDF file using Rails 3. I have a table with some values and i want to display these data in PDF. I have written some code which are explained below.
index.html.erb:
<h1>Choose the option</h1>
<p>
<%= link_to "new input",products_new_path %>
</p>
<table>
<tr>
<th>Product name</th>
<th>Product Catagory</th>
</tr>
<% #product.each do |p| %>
<tr>
<td><%= p.p_name %></td>
<td><%= p.p_catagory %></td>
</tr>
<% end %>
</table>
products_controller.rb:
class ProductsController < ApplicationController
def index
#product=Product.all
respond_to do |format|
format.html
format.pdf do
pdf = Prawn::Document.new
send_data pdf.render, filename: 'report.pdf', type: 'application/pdf'
end
end
end
def new
#product=Product.new
end
def create
#product=Product.new(params[:product])
if #product.save
flash[:notice]="Data submitted"
flash[:color]="valid"
redirect_to :action => "index"
else
flash[:alert]="Data could not finish"
flash[:color]="invalid"
render 'new'
end
end
end
Gemfile:
source 'https://rubygems.org'
gem 'rails', '3.2.19'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'
# To use Jbuilder templates for JSON
# gem 'jbuilder'
# Use unicorn as the app server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'debugger'
gem 'prawn'
config/initializer/mime_type.rb
Mime::Type.register "application/pdf", :pdf
Please help me to resolve this issue and also let me to know how can i run app(e.g-localhost:3000/products.pdf) for getting this pdf file.

What I would do is to add this line to your Gemfile to generate a table with prawn :
gem 'prawn-table'
Make sure you are using these version :
bundle show
# * prawn (2.0.1)
# * prawn-table (0.2.1)
In your controller, if you want to generate the PDF file when index action is called you can add this into it :
def index
#products = Product.all
require "prawn/table"
require "prawn"
Prawn::Document.generate("test.pdf") do |pdf|
table_data = Array.new
table_data << ["Product name", "Product category"]
#products.each do |p|
table_data << [p.name, p.category]
end
pdf.table(table_data, :width => 500, :cell_style => { :inline_format => true })
end
end
You can add some html syntax if you want to it :
["<b>#{p.name}</b>", "<i>#{p.category}</i>"]
Here is the result :

#satya, I'll suggest you to use 'prawn' and 'prawn-table' gem.
Steps to create pdf is -
1: #create pdf object
pdf = Prawn::Document.new()
2: #assign the value in pdf object
pdf.text "To Date - #{extra_data[:to_date]}"
For more info you can watch this vedio -
http://railscasts.com/episodes/153-pdfs-with-prawn

#satya, use this- - > return send_data Product.get_product_report_runtime_pdf(input_data), type: :pdf, filename: "Units_report_#{Time.now.strftime("%Y%m%d%H%M%S")}.pdf" will return the run time created pdf and if you want html page as well then dont use return before send data.
Under Product model -> here I am returning the blank pdf, so use the required code whatever you want in your pdf.
def get_product_report_runtime_pdf
pdf = Prawn::Document.new
return pdf.render
end

Related

Image upload on rails 4 using paperclip shows broken image

Before I begin, I would like to say that I have googled and tried multiple solutions that were offered. I am still encountering the same issue.
When I upload an image using paperclip, it displays a broken image. I right clicked and inspected and found that my page is raising and error : Get http://localhost:3000/system/pins/images/000/000/008/medium/imgres.jpg 404 (Not Found).
View
<%= image_tag #pin.image.url %>
<p>
<strong>Description:</strong>
<%= #pin.description %>
</p>
<% if #pin.user == current_user %>
<%= link_to 'Edit', edit_pin_path(#pin) %>
<%= link_to 'Back', pins_path %>
<% end %>
Model
class Pin < ActiveRecord::Base
belongs_to :user
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
end
Controller
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#pins = Pin.all
end
def show
end
def new
#pin = current_user.pins.build
end
def edit
end
def create
#pin = current_user.pins.build(pin_params)
if #pin.save
redirect_to #pin, notice: 'Pin was successfully created.'
else
render :new
end
end
def update
if #pin.update(pin_params)
redirect_to #pin, notice: 'Pin was successfully updated.'
else
render :edit
end
end
def destroy
#pin.destroy
redirect_to pins_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
#pin = Pin.find(params[:id])
end
def correct_user
#pin = current_user.pins.find_by(id: params[:id])
redirect_to pins_path, notice: "Not authorized to edit this pin" if #pin.nil?
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description, :image)
end
end
Gemfile
source 'https://rubygems.org'
ruby '2.2.6'
gem 'rails', '4.0.0'
gem 'sass-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
gem 'coffee-script-source', '1.8.0'
gem 'bootstrap-sass'
gem 'devise'
gem 'paperclip', '~> 4.2.0'
group :development, :test do
gem 'sqlite3'
end
group :production do
gem 'pg'
gem 'rails_12factor'
end
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
I've tried downgrading and upgrading my gem file, adding a cocaine gem, adding :path => "" and :url => "" to my model, setting the timestamp to false, restarting my computer and my server, uninstalling and reinstalling imagemagick, downloading the file.exe manually and adjusting the code to in development.rb as instructed, and changing the location of my image. I may be forgetting some things I've tried, because I've been searching on google and adjusting for hours now. Is there anyone who can help?
At a high level paperclip writes the uploaded file to a local file and stores information on the file in the database for lookup. The fact that rails is returning a 404 indicates that either 1) the file isn't being written or 2) rails isn't serving the file correctly.
The paperclip documentation on storage is pretty good as a reference: https://github.com/thoughtbot/paperclip#understanding-storage
By default rails should serve files that are in the public directory and by default paperclip stores files under public/system, so generally file serving should work in the development environment automatically.
Can you verify that the file public/system/pins/images/000/000/008/medium/imgres.jpg exists?

Rails 4, Strong Parameters, Unpermitted parameters on fields belonging to associated model

This is my first try at using models with associations with Rails 4 and for some reason I'm not able to get at the parameters POST'ed in due to a "Unpermitted parameters" error. I have tried to permit the associated fields several different ways with no success.
Basically, I have an Adoption Request with an associated Person.
class AdoptionRequest < ActiveRecord::Base
has_one :person
accepts_nested_attributes_for :person
end
and
class Person < ActiveRecord::Base
belongs_to :adoption_request
end
Here are the relevant sections from adoption_requests_controller.rb:
def create
#adoption_request = AdoptionRequest.new(adoption_request_params)
respond_to do |format|
if #adoption_request.save
format.html { redirect_to #adoption_request, notice: 'Adoption request was successfully created.' }
format.json { render action: 'show', status: :created, location: #adoption_request }
else
format.html { render action: 'new' }
format.json { render json: #adoption_request.errors, status: :unprocessable_entity }
end
end
end
private
def adoption_request_params
params.require(:adoption_request).permit(person_attributes: [:first_name, :last_name])
end
The form in the view is generated using rails-bootstrap-forms:
= bootstrap_form_for #adoption_request do |f|
= f.fields_for #adoption_request.person do |owner_fields|
= owner_fields.text_field :first_name
= owner_fields.text_field :last_name
= f.submit
Here is an example of the HTML generated by this for the first name field:
<input class="form-control" id="adoption_request_person_first_name" name="adoption_request[person][first_name]" type="text">
Now when I submit the following POST payload:
{"utf8"=>"✓", "authenticity_token"=>"kE1Q222VzXRsuLnhiO0X3mijW1TGTWSAOVgVDz/rxsE=", "adoption_request"=>{"person"=>{"first_name"=>"John", "last_name"=>"Smith"}}, "commit"=>"Create Adoption request"}
The adoption request is created, but the associated person is not. This is appears to be happening because strong parameters is not allowing the person parameters to come through. Case in point, I see this in the rails console output:
Unpermitted parameters: person
According to the strong parameters documentation, this configuration should work, but I have also tried:
params.require(:adoption_request).permit(:person, person_attributes: [:first_name, :last_name])
which results in the same error ("Unpermitted parameters: person"), and
params.require(:adoption_request).permit!
works to allow the parameters through, but this is not an acceptable solution as it negates the whole purpose of using strong parameters.
What am I doing wrong?
Here is my Gemfile, in case it is helpful:
source 'https://rubygems.org'
ruby '2.0.0'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.3'
# Use postgresql as the database for Active Record
gem 'pg'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
# Use Bootstrap
gem 'bootstrap-sass', '~> 3.3.4'
# Use Figaro to make using environment variables easier
gem 'figaro'
# Use Slim templating engine
gem "slim-rails"
# User authlogic for authentication system
gem 'authlogic'
# Use rails-bootstrap-forms to integrate rails form builder with bootstrap
gem 'bootstrap_form'
group :test do
# use MiniTest::Spec::DSL
gem 'minitest-spec-rails', '~> 4.7'
end
The app itself is more complex than this. I've simplified it to illustrate the problem.
Thanks in advance for your help!
You need to change this line
= f.fields_for #adoption_request.person do |owner_fields|
to
= f.fields_for :person do |owner_fields|
I would simply try building the Person object on save. Pass the first and last names up as hidden fields.
Otherwise I would give strong parameters a read.
if #adoption_request.save
#adoption_request.persons.build(first_name: #first_name, last_name: #last_name)

"Undefined method paginate" error message is coming while using will_paginate Gem

I am getting the following error when i am implementing will_paginate gem in my app.
Error:
NoMethodError in ProductsController#index
undefined method `paginate' for #<Array:0x2d25ae8>
app/controllers/products_controller.rb:3:in `index'
Please check my below code and please try to help me to resolve this.
Gemfile
source 'https://rubygems.org'
gem 'rails', '3.2.19'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'
# To use Jbuilder templates for JSON
# gem 'jbuilder'
# Use unicorn as the app server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'debugger'
gem 'will_paginate', '~> 3.0'
views/products/index.html.erb
<%= will_paginate #products %>
<table style="width:500px">
<thead>
<tr>
<th>Name</th>
<th style="text-align:right;">Price</th>
<th style="text-align:right;">Quantity</th>
</tr>
</thead>
<tbody>
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td style="text-align:right;"><%= number_to_currency product.price %></td>
<td style="text-align:right;"><%= product.quantity %></td>
</tr>
<% end %>
</tbody>
</table>
<%= will_paginate #products %>
controller/products_controller
class ProductsController < ApplicationController
def index
#products = Product.all.paginate(page: params[:page], per_page: 5)
end
end
Please try to help me.
Ah, just noticed you're on rails 3. In that case, try this instead:
#products = Product.paginate(page: params[:page], per_page: 5)
The difference is the lack of #all, which returns an Array on rails 3.

Cannot get my Articles controller to create a blog Article with a picture. I am using imagemagick and carrierwave

My create action in ArticlesController seems fine if I create an Article without uploading a picture. However, if I try to upload a picture for an article, I get the error:
ActionController::UrlGenerationError in ArticlesController#create
No route matches {:action=>"show", :controller=>"articles", :id=>nil} missing required keys: [:id]
Here is my Articles controller:
class ArticlesController < ApplicationController
before_filter :require_login, only: [:new, :create, :edit, :update, :destroy]
def index
#articles = Article.all
end
def show
#article = Article.find(params[:id])
#comment = Comment.new
#comment.article_id = #article.id
end
def new
#article = Article.new
end
def create
#article = Article.new(article_params)
#article.save
redirect_to article_path(#article)
end
def edit
#article = Article.find(params[:id])
end
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
def update
#article = Article.find(params[:id])
#article.update(article_params)
flash.notice = "Article '#{#article.title}' Updated!"
redirect_to article_path(#article)
end
private
def article_params
params.require(:article).permit(:title, :body, :tag_list, :picture)
end
end
Here is my Article model:
class Article < ActiveRecord::Base
has_many :comments
has_many :taggings
has_many :tags, through: :taggings
mount_uploader :picture, PictureUploader
validate :picture_size
def tag_list
self.tags.collect do |tag|
tag.name
end.join(", ")
end
def tag_list=(tags_string)
tag_names = tags_string.split(",").collect{|s| s.strip.downcase}.uniq
new_or_found_tags = tag_names.collect { |name| Tag.find_or_create_by(name: name) }
self.tags = new_or_found_tags
end
# Validates the size of an uploaded picture.
def picture_size
if picture.size > 5.megabytes
errors.add(:picture, "should be less than 5MB")
end
end
end
My Gemfile :
source 'http://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.1.8'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.3'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
gem 'carrierwave', '0.10.0'
gem 'mini_magick', '~> 4.0.4'
gem 'fog', '~> 1.27.0'
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
gem 'sorcery'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'
# Use unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
# Use debugger
# gem 'debugger', group: [:development, :test]
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin]
And finally my picture uploader:
# encoding: utf-8
class PictureUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
process resize_to_limit: [500, 500]
if Rails.env.production?
storage :fog
else
storage :file
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :resize_to_fit => [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
What am I doing wrong with carrierwave and Imagemagic to get
this error ?

Uninitialized Constant MessagesController

I'm building a simple chat app based on this rails cast. I'm following along fine, but when I go to localhost, I get an error "uninitialized constant MessagesController::Message". This is generally a simple fix, but I have spent over an hour looking for the fix and I cannot see it. Here is my code;
messages_controller
class MessagesController < ApplicationController
def index
#messages = Message.all
end
def create
#message = Message.create!(params[:message])
PrivatePub.publish_to("/messages/new", "alert('#{#message.content}');")
end
end
model (message.rb)
class Message
end
index & message form (index.html.erb);
<h1>Hack Chat</h1>
<ul id="chat">
<%= render #messages %>
</ul>
<%= form_for Message.new, remote: true do |f| %>
<%= f.text_field :content %>
<%= f.submit "Send" %>
<% end %>
<%= subscribe_to "/messages/new" %>
routes.rb;
Hackchat::Application.routes.draw do
root to: 'messages#index'
resources :messages
end
gemfile;
source 'https://rubygems.org'
gem 'rails', '4.0.0'
gem 'sqlite3'
group :assets do
gem 'sass-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
end
gem 'jquery-rails'
gem 'private_pub'
gem "thin", "~> 1.6.1"
I have checked every possible thing I could think of as to why I would be getting this error, and I really do not know why. Any help would be much appreciated.
Also, for using private pub, do I have to run two terminal windows, one running rails server, and the other running faye?
Your model is #Messages, change it to #message.
To change it like you should use migration:
def change
rename_table :old_table_name, :new_table_name
end
Of course do not create that file by hand but use rails generator:
rails g migration ChangeMessagesToMessage
That will generate new file with proper timestamp in name in 'db dir. Then run:
rake db:migrate
And your app should be fine since then.

Resources