Selecting months during PDF export with form submit. - ruby-on-rails-3

I have a Rails 3.2 application with a model called Mileages. I have added a PDF output of the mileages index action using Prawn PDF.
The mileages_controller's index action looks like this:
def index
#mileages = Mileage.find_all_by_user_id(current_user.id)
#mileages_months = Mileage.find_all_by_user_id(current_user.id).group_by { |t| t.created_at.beginning_of_month }
respond_to do |format|
format.html # index.html.erb
format.json { render json: #mileages }
format.pdf do
pdf = MileagePdf.new(#mileages, view_context)
send_data pdf.render, filename: "mileages_report.pdf",
type: "application/pdf",
disposition: "inline"
end
end
end
What I would like to do, is have a link on the index view to the PDF version but alongside would be a start date and an end date. The PDF would then only show the mileage entries between those two dates.
The PDF link would simply be <%= link_to "Mileage Report (PDF)", mileages_path(#mileages, format: "pdf") %>
The activerecord filter would, presumably, be something like this:
#mileages = Milage.where(:date => ??..??)
I am unsure how to tie the above to the date inputs. Any help would be appreciated!

Try to have a kind of form submit since you have dates.
<%= form_tag(mileages_path(format: :pdf), method: :get) do -%>
<%= date_select("mileage_start", "date", order: [:year,:month,:day])%>
<%= date_select("mileage_end", "date", order: [:year,:month,:day])%>
<%= submit_tag %>
<%end%>
UPDATED with Final answer from chat
def index
start_date = params[:mileage_start]
end_date = params[:mileage_end]
if start_date && end_date
dates = get_start_and_end_date(start_date,end_date)
#mileages_pdf = Mileage.where(date: dates[:start_date]..dates[:end_date])
end
respond_to do |format|
# format.html # index.html.erb
# format.json { render json: #mileages }
format.pdf do
pdf = MileagePdf.new(#mileages_pdf, view_context)
send_data pdf.render, filename: "mileages_report.pdf",
type: "application/pdf",
disposition: "inline"
end
end
end
def get_start_and_end_date(start_date,end_date)
hsh = {}
hsh[:start_date] = build_date(start_date)
hsh[:end_date] = build_date(end_date)
hsh
end
def build_date(hsh)
DateTime.new(hsh["date(1i)"].to_i,hsh["date(2i)"].to_i,hsh["date(3i)"].to_i)
end
This way you can capture the date from params and format it in the way you want and place it in your query.

Related

Rails Prawn converting my index table into a pdf

I am trying to create a .pdf that lists all of my projects(#index).
I found a great link-How do generate PDFs in Rails with Prawn, however it was from 2008 and wanted me to use the prawnto plugin.
I am using Rails 3.2.13 so I decided to use the gem prawn and RailsCast #153 PDFs with Prawn (revised), for reference. I was able to successfully get Prawn working in my:
projects_controller
def show
I am having trouble getting the .pdfs working in my def index though.
I tried to just mimic what I did, using the tutoiral for def show, for def index but am getting a routing error.
Here is my code thus far:
Gemfile
gem 'prawn', '0.12.0'
projects_controller.rb
class ProjectsController < ApplicationController
def index
redirect_to action: :active, search =>params[:search]
end
def active
#action = "active"
....
.... // search code
.... // kaminari code
#projects = Project.order(sort_column + "" + sort_direction)
respond_to do |format|
format.json { render "index" }
format.html { render "index" }
format.pdf do
pdf = ProjectAllPdf.new(#projects)
send_data pdf.render, filename: "project_#{#project.product}.pdf",
type: "application/pdf",
disposition: "inline"
end
end
end
def show
#project = Project.find(params[:id])
respond_to do |format|
format.json { render json:#project }
format.html # show.html.erb
format.pdf do
pdf = ProjectPdf.new(#project)
send_data pdf.render, filename: "project_#{#project.product}.pdf",
type: "application/pdf",
disposition: "inline"
end
end
end
end
show.html.erb
<p><%= link_to "Printable Receipt (PDF)", project_path(#project, format: "pdf") %></p>
index.html.erb
<p><%= link_to "Printable Receipt (PDF)", projects_path(#projects, format: "pdf") %></p>
I then formatted my file
project_pdf.rb
class ProjectPdf < Prawn::Document
def initialize(project)
super(top_margin: 70)
#project = project
overview_print
end
def overview_print
text "Project #{#project.product}", size: 24, style: :bold, align: :center
move_down 30
text "<b>Product:</b> #{#project.product}", :inline_format => true
move_down 8
text "<b>Version Number:</b> #{#project.version_number}", :inline_format => true
move_down 8
....
....
end
end
I then tried to mimic the last file to get #index working
projectall_pdf.rb
class ProjectAllPdf < Prawn::Document
def initialize(project)
super(top_margin: 70)
#project = project
overview_print
end
def overview_print
#projects.each do |project|
text "<b>Product:</b> #{#project.product}", :inline_format => true
move_down 8
text "<b>Version Number:</b> #{#project.version_number}", :inline_format => true
move_down 8
....
....
end
end
end
Everything works great for #show. I just obviously have gotten myself mixed up on how to do the #index portions (def active, linking the .pdf in index.html.erb and projectall_pdf.rb)
I thought I would post an answer to my question, hopefully it helps somebody.
I actually went ahead and used the 'gem prawnto_2', :require => "prawnto"
It allowed me to use the prawnto and the prawnto tutorial with Rails 3.2
I then just created (method).pdf.prawn pages in my app/views/projects folder.
Then just add your custom pdf code to have you want to layout your pdf views.

Nested Routing with a Collection in Rails

I'm getting an error: No route matches {:action=>"sort", :controller=>"links"}
I'm adapting from a non-nested example and am having trouble figuring out the nested routing.
Right now, my route looks like this:
resources :groups do
resources :navbars do
resources :links do
collection { post :sort }
end
end
post :add_user, on: :member
end
I am rendering a collection of links from navbar>show:
= render partial: 'links/link', collection: #navbar.links
and here's the collection, links>_link.html.haml:
%ul#links{"data-update-url" => sort_group_navbar_links_url}
- #links.each do |faq|
= content_tag_for :li, link do
%span.handle [drag]
= link.method_name
= link.code
= link.button
= link.text
= link_to 'Edit Link', edit_group_navbar_link_path(#group, #navbar, link), class: 'btn btn-mini'
= link_to 'Delete', group_navbar_link_path(#group, #navbar, link), data: { confirm: 'Are you sure?' }, method: :delete, class: 'btn btn-mini'
My links_controller has the sort action:
def sort
params[:link].each_with_index do |id, index|
Link.update_all({display_order: index+1}, {id: id})
end
render nothing: true
end
Because my link collection is being rendered from the navbar>show page, it's not clear to me where my sort action should be located (in links_controller or in navbars_controller).
And my navbars_controller defines #links:
def show
#links = #navbar.links.order("display_order")
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #navbar }
end
end
Also here's the js for good measure (links.js.coffee):
jQuery ->
$('#links').sortable
axis: 'y'
handle: '.handle'
update: ->
$.post($(this).data('update-url'), $(this).sortable('serialize'))
Maybe this last line also needs work to include the route?
I'm using rails 3.2.

No route matches {:action=>"show", :controller=>"restaurants"}

If I want to go with my home page clicking on the map localhost:3000/maps gets out this error No route matches {:action=>"show", :controller=>"restaurants"}
controllers/maps_controller.rb
def index
#maps = Map.all
#json = Map.all.to_gmaps4rails do |map, marker|
marker.infowindow info_for_restaurant(map.restaurant)
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
def show
#map = Map.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #map }
end
end
private
def info_for_restaurant(restaurant)
link_to restaurant_path do
content_tag("h2") do
restaurant.name
end
end
end
routes.rb
resources :restaurants
resources :maps
This is answer for my question:
controllers/maps_controller.rb
def index
#maps = Map.all
#json = Map.all.to_gmaps4rails do |map, marker|
marker.infowindow render_to_string(:partial => "/maps/maps_link",
:layout => false, :locals => { :map => map})
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
views/maps/_maps_link.html.erb
<div class="map-link">
<h2><%= link_to map.restaurant.title, map.restaurant %></h2>
</div>
You referred to restaurant_path within info_for_restaurant, which is part of MapsController. Rails met error here.
You need to either define the restaurant_path in restaurant controller, or comment out this function in maps controller at this moment.
Your approach is wrong in several levels. Let's work on them, one at a time:
1) Your call to the route helper is wrong:
restaurant_path is the route helper for a show action. A show action needs an id parameter to be valid. Your call is missing a parameter.
So, your code must be something like this:
def info_for_restaurant(restaurant)
link_to restaurant_path(restaurant) do
content_tag("h2") do
restaurant.name
end
end
end
To see the parameters needed for each action, you can run rake routes on the console.
However, this does not solve the problem, as you're also:
2) Calling view helpers from your controller
link_to and content_tag are view helper methods, and you don't want to bother your controller with view issues. So, the best way to solve this problem is to move your info_for_restaurant method to a helper, and call it from a view instead.
So, now, your controller will not assign anything to #json, and the last line of your view will look like this:
<%= gmaps4rails #maps.to_gmaps4rails {|map, marker| marker.infowindow info_for_restaurant(map.restaurant) } %>

Rails undefined method `map' for nil:NilClass

I'm trying to create a select field for a form that selects based on records selected for a model (called "Cancellation_Reasons").
In my model called Cancellation:
<%= form_for(#cancellation do |f| %>
<%= options_from_collection_for_select(#cancellation_reasons, :id, :name) %>
<% end %>
In the Cancellation_Controller:
def new
#cancellation = Cancellation.new
#cancellation_reasons = CancellationReason.find(1)
respond_to do |format|
format.html # new.html.erb
format.json { render json: #trade }
end
end
When I run CancellationReason.find(1) in the the Rails Console it finds the record, so #cancellation_reasons isn't nil. I think that it's probably in how I'm using the select helpers (I've tried experimenting with them, but I'm not quite sure which one to use even after reading the Rails Guide and Rails API docs).
options_from_collection_for_select expect a collection (even it it is a collection of 1).
So change the code to be:
def new
#cancellation = Cancellation.new
#cancellation_reasons = CancellationReason.all
respond_to do |format|
format.html # new.html.erb
format.json { render json: #trade }
end
end

Rendering a like/unlike button in rails with jQuery

I'm using jquery to render a like button on a story. I have two models story and like
Here's the likes controller code:
def create
#like = Like.new(params[:like])
#story = Story.find(params[:story])
#like.story = #story
if #like.save
respond_to do |format|
format.html
format.js
end
end
end
def destroy
#like = Like.find(params[:id])
##story = #like.story
#like.destroy
respond_to do |format|
format.html { redirect_to stories_url }
format.js
format.json { head :ok }
end
end
This is the button partial (stories/like_button):
<% unless user_likes_story?(#story, current_user) %>
<%= button_to 'like', "/likes?story=#{#story.id}", :id => 'like_button', :remote => true %>
<% else %>
<%= button_to 'liked', #liked, :class => 'like_button unlike', :id => 'unlike_button', :remote => true, method: :delete %>
<% end %>
The problem is that my create.js.erb, when rendering the 'unlike' button, doesn't properly load the #liked instance variable, because it's being set in the #show action of the stories controller before the user has liked the story, so I can't figure out how or where to set it so the JS will render the unlike properly. I'm probably making this harder than it has to be, but...
create.js.erb
$('.button_to').replaceWith('<%=j render 'stories/like_button' %>');
$('#story_likes_count').replaceWith('<%=j render 'stories/likes_count' %>');
Here's how I tried setting #liked, in stories#show
def show
#like = Like.new
#story = Story.find(params[:id])
if current_user
#liked = Like.find_by_user_id_and_story_id(current_user,#story)
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: #story }
end
end
Any idea how to do this properly? Should I just move the partial out of the stories folder?
The solution was pretty simple. In the controller, doing this:
format.js {#liked = #like}
Passes the variable and makes it available to the partial when it's rendered.