I was trying to add csv for my the search results but it throws error telling unpermitted params. What params should i pass in the csv link? So that csv would download the only the search results.
ReportsController
def revenue_search
#bookings = Booking.complete.order("created_at DESC")
date = "1-#{params['date']['month']}-#{params['date']['year']}"
date = Date.parse(date)
#bookings = #bookings.where(created_at: date.beginning_of_month..date.end_of_month)
#per_page = params[:per_page] || Booking.per_page || 20
#bookings = #bookings.paginate( :per_page => #per_page, :page => params[:page])
if params[:currency].present?
#bookings = #bookings.where(currency: params[:currency])
end
respond_to do |format|
format.html
format.csv { send_data #bookings.revenue_csv }
end
end
Model
def self.revenue_csv
attributes = %w{ total value deposit balance }
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |booking|
csv << attributes.map{ |attr| booking.send(attr) }
end
end
end
revenue.html.erb
<%= form_tag revenue_search_path, :method => 'get' do %>
<%= select_tag(:currency, options_for_select(["USD", "GBP"]), class: "form-control custom-select" , :prompt => 'By Office' ) %>
<%= select_month((#selected_date || Date.today), {}, class:"custom-select", :prompt => 'By Month')%>
<%= select_year((#selected_year || Date.today.year), {}, class:"custom-select" )%>
<%= submit_tag "Search", name: nil , class: "btn btn-info" %>
<% end %>
<table id="demo-foo-addrow" class="table m-t-30 table-hover no-wrap contact-list no-paging footable-loaded footable" data-page-size="2">
<thead>
<tr>
<th class="footable-sortable">Total No of students<span class="footable-sort-indicator"></span></th>
<th class="footable-sortable">Value of courses sold<span class="footable-sort-indicator"></span></th>
<th class="footable-sortable">Total Deposits<span class="footable-sort-indicator"></span></th>
<th class="footable-sortable">Balance payments<span class="footable-sort-indicator"></span></th>
</tr>
</thead>
<tbody>
<tr>
<td><%= #bookings.count %></td>
<td><%= #bookings.count %></td>
<td><%= #bookings.sum{|x| (x.payment_gross.to_f)} %></td>
<td><%= #bookings.sum{|x| (x.course&.course_fee || x.event&.course_fee).to_f - x.payment_gross.to_f }.to_f %></td>
</tr>
</tbody>
</table>
<p> Download: <%= link_to "CSV", revenue_search_path(format: "csv" , params: params ) %> </p>
logs:
ActionView::Template::Error (unable to convert unpermitted parameters to hash):
42: </div>
43: </div>
44: </div>
45: <p> Download: <%= link_to "CSV", revenue_search_path(format: "csv" , params: params ) %> </p>
app/views/reports/revenue_search.html.erb:45:in `_app_views_reports_revenue_search_html_erb___71501213_135144540'
You can use to_unsafe_h
revenue_search_path(format: "csv" , params: params.to_unsafe_h)
Related
my controller
class IndustryController < ApplicationController
def index
#industries=Industry.all
end
def new
#industry=Industry.new
end
def create
#industry = Industry.new(industry_params)
# #industry = Industry.new(params[:name_bef,:name,:status])
# #industry = Industry.new(:name_bef => (params[:name]),:name => (params[:name]), :status => (params[:status]))
if #industry.save
redirect_to industry_index_path
else
render 'new'
end
end
def update
#industry = Industry.all
#industry.each do |i|
#industry.find(i.id)
#industry.update(industry_params)
end
end
private
def industry_params
params.require(:industry).permit(:name, :status)
end
private
def industry_update
params.require(:industry).permit(:name, :status)
end
end
my html
<%= form_for #industries, as: :industry, url: industry_path(#industries), method: :patch do |f| %>
<table class="table table-bordered">
<thead class="bg-light">
<tr>
<th scope="col">業種名(変更前)</th>
<th scope="col">業種名</th>
<th scope="col">状態</th>
</tr>
</thead>
<tbody>
<% #industries.each do |industry| %>
<tr>
<td><%= industry.name %></td>
<td>
<div class="form-group">
<%= f.text_field :name, :value => industry.name, :id => industry.id, :class => "form-control" %>
</div>
</td>
<td>
</td>
</tr>
<% end %>
</tbody>
</table>
<div class="form-group text-center">
<%= f.submit"登録", :class => " btn btn-success" %>
</div>
<%end%>
My assumption is that you are talking about the update action in your controller. It looks like update_all is the method you are looking for.
def update
Industry.update_all(industry_params)
end
This can be dangerous - be aware that this will bypass active record validations and callbacks, so make sure you are certain.
I am learning to use CRUD, and setup a page to add a record, however it only generated blank record? Can you take a look my code?
thanks!
here is the Page controller:
class PagesController < ApplicationController
def index
#test = Page.all
end
def new
#test = Page.new
end
def create
#test = Page.new(params.permit(:subject_id,:name,:position,:visible,:permalink))
if #test.save
flash[:notice] = "Page created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
end
here is the new.html.erb
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="pages new">
<h2>Create Subject</h2>
<%= form_for(:Page, :url => {:action => 'create'}) do |f| %>
<table summary="Page form fields">
<tr>
<th>Subject_ID</th>
<td><%= f.text_field(:subject_id) %></td>
</tr>
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible</th>
<td><%= f.text_field(:visible) %></td>
</tr>
<tr>
<th>Permalink</th>
<td><%= f.text_field(:permalink) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Here is index.html.erb
<div class="pages index">
<h2>Pages</h2>
# <%= link_to("Add New Page", {:action => 'new'}, :class => 'action new') %>
<table class="listing" summary="Page list">
<tr class="header">
<th>Position</th>
<th>Page Name</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<% #test.each do |f| %>
<tr>
<td><%= f.position %></td>
<td><%= f.name %></td>
<td class="center"><%= f.visible %></td>
<td class="center"><%= f.permalink %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => f.id}, :class => 'action show') %>
<%= link_to("Edit", {:action => 'edit', :id => f.id}, :class => 'action edit') %>
<%= link_to("Delete", {:action => 'delete', :id => f.id}, :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
</div>
Thanks so much!
Strong parameters
Rails sends form parameters in nested hashes.
{ page: { subject_id: 1, name: 'Hello World.' } }
So to whitelist the parameters you would do.
class PagesController < ApplicationController
def index
#test = Page.all
end
def new
#test = Page.new
end
def create
#test = Page.new(page_params)
if #test.save
flash[:notice] = "Page created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
private
def page_parameters
params.require(:page)
.permit(:subject_id,:name,:position,:visible,:permalink)
end
end
which is like doing:
params[:page].slice(:subject_id,:name,:position,:visible,:permalink)
form_for and models
Also your form should read:
<%= form_for(:page, :url => {:action => 'create'}) do |f| %>
Or:
<%= form_for(#page, :url => {:action => 'create'}) do |f| %>
:Page will give you the wrong key in your parameters and prevent rails from binding the form to your #page object. (The values posted will disappear from the form when it's invalid).
I have controller looks like :
## controllers/lhgs_controller.rb
def index
#per_page = params[:per_page] || 10
#totalsolds = Totalsold.paginate(:per_page => #per_page, :page => params[:page]).order('date asc').group_by{ |s| [s.date, s.store_id, s.nomor] }
end
And views :
## index.hmtl.erb
<div id="totalsolds"><%= render 'totalsolds' %></div>
## views/_totalsolds.html.erb
<% #totalsolds.each do |(date, store, nomor), totalsold| %>
<tr>
<td><%= date.strftime("%d/%m/%Y") %></td>
<td><%= nomor %></td>
<td><%= Store.find(store).name %></td>
<% totalsold.each do |ts| %>
<td><%= ts.qty == 0 || ts.qty == nil ? "-" :prod.qty %></td>
<% end %>
<td>Rp<%= number_to_currency(totalsold.sum(&:value), :unit => "") %></td>
<td><%= link_to "edit", edit_bt_path(:store_id => store, :date => date, :nomor => nomor), :class => "btn btn-primer" %></td>
</tr>
<% end %>
...
...
<div class="row">
<div class="col-sm-6">
<% line 65 %>
<%= page_entries_info #totalsolds %>
</div>
<div class="col-sm-6">
<%= will_paginate #totalsolds, :style => 'float:right;margin-top:-5px;height:30px;' %>
</div>
</div>
I got an error :
ArgumentError in Lhgs#index
Showing C:/Sites/cms/app/views/lhgs/_totalsolds.html.erb where line
65 raised:
The #lhgs variable appears to be empty. Did you forget to pass the
collection object for will_paginate?
I found same question and solution, but I can't figure out how to use it for my case.
UPDATE :
I'm not found anywhere #lhgs variable, I tried to change #totalsolds to #lhgs and now my controller lookslike :
## controllers/lhgs_controller.rb
def index
#per_page = params[:per_page] || 10
#lhgs = Totalsold.order('date asc').group_by{ |s| [s.date, s.store_id, s.nomor] }
#lhgs = #lhgs.paginate(:per_page => #per_page, :page => params[:page])
end
And this an error :
NoMethodError in LhgsController#index
undefined method `paginate' for #<Hash:0x4c034a0>
Use rails console :
irb(main):001:0> #lhgs = Totalsold.order('date asc').group_by{ |s| [s.date, s.store_id, s.nomor] }
.... look at pastebin ......
irb(main):002:0> #lhgs.class
=> Hash
pastebin
Solved
reference
On controller :
def index
#per_page = params[:per_page] || 10
#lhgs = Totalsold.order('date asc').group_by{ |s| [s.date, s.store_id, s.nomor] }
#lhgs_keys = #lhgs.paginate(:per_page => #per_page, :page => params[:page])
end
And on view :
<% #lhgs_keys.each do |k| %>
<% #lhgs[k].group_by{ |s| [s.date, s.store_id, s.nomor] }.each |(date, store, nomor), totalsold| %>
.....
....
<% end %>
<% end %>
<div class="row">
<div class="col-sm-6">
<% line 65 %>
<%= page_entries_info #lhgs_keys %>
</div>
<div class="col-sm-6">
<%= will_paginate #lhgs_keys, :style => 'float:right;margin-top:-5px;height:30px;' %>
</div>
</div>
Try it like this:
# controllers/lhgs_controller.rb
def index
#per_page = params[:per_page] || 10
#totalsolds = Totalsold.paginate(:per_page => #per_page, :page => params[:page]).order('date asc').group_by{ |s| [s.date, s.store_id, s.nomor] }
respond_to do |format|
format.html
end
end
And the index.html can be like this:
<% #totalsolds.each do |(date, store, nomor), totalsold| %>
<tr>
<td><%= date.strftime("%d/%m/%Y") %></td>
<td><%= nomor %></td>
<td><%= Store.find(store).name %></td>
<% totalsold.each do |ts| %>
<td><%= ts.qty == 0 || ts.qty == nil ? "-" :prod.qty %></td>
<% end %>
<td>Rp<%= number_to_currency(totalsold.sum(&:value), :unit => "") %></td>
<td><%= link_to "edit", edit_bt_path(:store_id => store, :date => date, :nomor => nomor), :class => "btn btn-primer" %></td>
</tr>
<% end %>
...
<div class="row">
<div class="col-sm-6">
<% line 65 %>
<%= page_entries_info #totalsolds %>
</div>
<div class="col-sm-6">
<%= will_paginate #totalsolds, :style => 'float:right;margin-top:-5px;height:30px;' %>
</div>
</div>
I have a problem with Downloading csv files from my rails app.
First the controller looks like this;
def report
#report = SentMessage.where('user_id = ? AND created_at <= ? AND created_at >= ?', current_user.id, params[:before], params[:after]).order('created_at Desc')
respond_to do |format|
format.html
format.csv do
response.headers["Content-Type"] = "text/csv; charset=UTF-8; header=present"
response.headers["Content-Disposition"] = "attachment; filename=sent_messages.csv"
end
end
end
then my report.csv.erb file looks like this;
<%= provide(:title, "Sent Messages") %>
<div>
<div class="panel radius"> <h2 class="text_center">Sent Messages</h2></div>
<table class="table table-striped table-bordered table-hoverlarge-12 radius columns large-centered" id="sent_table">
<thead>
<tr>
<th>To</th>
<th>From</th>
<th>Message</th>
<th>Delivery Report</th>
<th>cost</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<% #report.each do |message| %>
<tr>
<td><%= message.to %></td>
<td><%= message.from %></td>
<td><%= message.message %></td>
<td><%= message.delivery %></td>
<td><%= message.cost %></td>
<td><%= message.created_at.to_datetime.strftime("%b %d, %Y %I:%M%P") %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
When i click the download link, the downloaded file is just empty besides the headers as show in the report.csv.erb file.
What could be the problem?
I simply had to change the link to the download from;
to
<%= link_to "Download CSV", params.merge(format: "csv"), class: "button radius" %>
And it worked.
Do like that may be work for you.
def report
#report = SentMessage.where('user_id = ? AND created_at <= ? AND created_at >= ?', current_user.id, params[:before], params[:after]).order('created_at Desc')
respond_to do |format|
format.html
format.csv{
response.headers["Content-Type"] = "text/csv; charset=UTF-8; header=present"
response.headers["Content-Disposition"] = "attachment; filename=sent_messages.csv"}
end
end
I'm fairly new to Ruby on Rails, making a directory type of website as a personal project to learn.
In my app, I implemented Geocoder search so the user can search for places/locations near them, the search worked perfect. But then when I added tabbed menus to categorize what type of places are available it broke the search.
I think I know why it's broken but not sure how to fix it. The tabs are showing the #schools, #restaurants, and #businesses variables, how can I get the tabs to show the search results and not those variables? Those variables should only show up when there is no search executed, but they also show up when the search is executed.
Here's my code:
Places Controller:
class PlacesController < ApplicationController
before_filter :authenticate_user!, except: [:index]
def index
if params[:search].present?
#places = Place.near(params[:search], 50, :order => :distance)
else
#places = Place.all
end
#schools = Place.where("category = ?", "School")
#restaurants = Place.where("category = ?", "Restaurant")
#businesses = Place.where("category = ?", "Business")
end
Places Index.html.erb:
<% if user_signed_in? %>
<div class="row">
<h2>Newly Added Places</h2>
<%= form_tag places_path, :method => :get do %>
<%= text_field_tag :search, params[:search], placeholder: "Enter your zipcode or city", class: "search-query" %>
<%= submit_tag "Search Nearby", :name => nil, class: "btn"%>
<% end %>
<ul class="nav nav-tabs">
<li>Schools</li>
<li>Restaurants</li>
<li>Businesses</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<%= render :partial => "places", :locals => {:places_container => #schools} %>
</div>
<div class="tab-pane" id="tab2">
<%= render :partial => "places", :locals => {:places_container => #restaurants} %>
</div>
<div class="tab-pane" id="tab3">
<%= render :partial => "places", :locals => {:places_container => #businesses} %>
</div>
</div>
</div>
<br />
<% else %>
<%= render 'static_pages/home' %>
<% end %>
Places partial(_places.html.erb):
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Image</th>
<th>Name</th>
<th>Address</th>
<th>State</th>
<th>City</th>
<th>Type</th>
<th>Website</th>
</tr>
</thead>
<% places_container.each do |place| %>
<tr>
<th><%= image_tag place.image(:medium)%></th>
<th><%= link_to place.name, place %></th>
<td><%= place.address %></td>
<td><%= place.state %></td>
<td><%= place.city %></td>
<td><%= place.category %></td>
<td><%= place.website %></td>
<% if current_user.admin? %>
<td><%= link_to 'Edit', edit_place_path(place) %></td>
<td><%= link_to 'Destroy', place, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</table>
Your tabbed results are ignoring the search parameter because you aren't using the #places relation built from the search parameter. To fix, change this code:
def index
if params[:search].present?
#places = Place.near(params[:search], 50, :order => :distance)
else
#places = Place.all
end
#schools = Place.where("category = ?", "School")
#restaurants = Place.where("category = ?", "Restaurant")
#businesses = Place.where("category = ?", "Business")
end
to:
def index
if params[:search].present?
#places = Place.near(params[:search], 50, :order => :distance)
else
#places = Place.scoped # use 'scoped', not 'all', to avoid triggering the query immediately
end
#schools = #places.where("category = ?", "School")
#restaurants = #places.where("category = ?", "Restaurant")
#businesses = #places.where("category = ?", "Business")
end