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
Related
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)
I'm trying to add a search bar for a database website I created, I found a tutorial and I "think" I did it correct.
When I do a search, such as "Judy Zhang", nothing shows up, even though it is in the database
my vendor.rb/concerns/models/app file
class Vendor < ApplicationRecord
has_many :fotos
def self.search(search)
if search
Vendor.where('lower(contact_name) LIKE ?', "'%#{search.downcase}%'")
else
Vendor.all
end
end
end
I believe I didn't do the coding right. Very new to ruby on rails. What did I do wrong here?
code for index.html.erb/vendors/views/layouts/app
<body>
<div class = "head">
<h1>Vendors </h1>
<div class = "image1" >
<img src= "http://dx.deucex.com/i/logo.png" >
</div>
</div>
</body>
<table>
<tr>
<%= button_to "New Vendor", new_vendor_path, :method => "get" %>
<%= button_to "Inventory", inventories_path, :method => "get" %>
<%= form_tag vendors_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</tr>
</table>
<table>
<tr>
<th>Company</th>
<th>Contact Name</th>
<th>Phone</th>
<th>Email</th>
</tr>
<% for vendor in #vendors %>
<tr>
<td><%= vendor.company %></td>
<td><%= vendor.contact_name %></td>
<td><%= vendor.phone %></td>
<td><%= vendor.email %></td>
<body>
<div class = "button1" >
<td><%= button_to "Show", vendor_path(vendor), :method => "get" %></td>
</div>
</body>
<td><%= button_to "Edit", edit_vendor_path(vendor), :method => "get" %></td>
<div class = "button3">
<td><%= button_to 'Delete',
vendor_path(vendor),
method: :delete,
data: { confirm: 'Are you sure?'} %></td>
</div>
</tr>
<% end %>
</table>
code for my VendorsController.rb/concerns/controller/app
class VendorsController < ApplicationController
def index
#vendors = Vendor.search(params[:search])
end
def show
#vendor = Vendor.find(params[:id])
end
def new
#vendor = Vendor.new
end
def create
#vendor = Vendor.new(vendor_params)
if #vendor.save
redirect_to #vendor
else
render 'new'
end
end
def edit
#vendor = Vendor.find(params[:id])
end
def update
#vendor = Vendor.find(params[:id])
if #vendor.update (vendor_params)
redirect_to #vendor
else
render 'edit'
end
end
def destroy
#vendor = Vendor.find(params[:id])
#vendor.destroy
redirect_to vendors_path
end
end
private
def vendor_params
params.require(:vendor).permit(:company, :contact_name, :phone, :email, :moq, :cost_per_item, :payment_method, :terms, :turnover, :returns, :notes)
end
Try changing the code in Vendor to
class Vendor < ApplicationRecord
has_many :fotos
def self.search(search)
if search
Vendor.where('lower(name) LIKE ?', "'%#{search.downcase}%'")
else
Vendor.all
end
end
end
My search bar isn't showing up
You should change the following
<% form_tag vendors_path, :method => 'get' do %>
to
<%= form_tag vendors_path, :method => 'get' do %>
# Notice that <%= %> evaluates and prints the output
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>
Now, I tried to set up the route with group_path(#group) but got an error message like,
ActiveRecord::RecordNotFound at /groups/%23%3CActiveRecord::Relation:0x007fd6cf362538%3E
Couldn't find Group with id=#<ActiveRecord::Relation:0x00fds6cf362538>
Here is my code. I would like to set up a link to groups/show/:id. Why did this error occur? Could you give me how to solve this?
☆index.html.erb
<% if #items.present? %>
<% #items.each do |i| %>
<% i_attr = i.get_element('ItemAttributes') %>
<tr>
<td> <%= link_to image_tag(i.get('SmallImage/URL'), {:style => 'border: none;'}), i_attr.get('DetailPageURL') %></td>
<td> <%= link_to i_attr.get('Title'), i_attr.get('DetailPageURL') %></td>
<td> <%= i_attr.get('Author') %></td>
<td> <%= i_attr.get('PublicationDate')%></td>
<td> <%= i_attr.get('Publisher') %></td>
<td> <%= i_attr.get('NumberOfPages')%></td>
<td>
<% if #existing_groups_isbns.include? i_attr.get('ISBN') %>
<% #existing_groups_isbns.each do |isbn| %>
<% if isbn == i_attr.get('ISBN') %>
<% #group = Group.where(:isbn =>isbn) %>
<%= link_to '既存ページへ' , group_path(#group) %>
<% end %>
<% end %>
<% else %><!-- if includes?==-->
<%= link_to '新規作成', {:controller => 'groups', :action => 'new', :name => i.get('ItemAttributes/Title'),:author => i.get('ItemAttributes/Author'), :publish => i.get('ItemAttributes/Publisher'), :published => i.get('ItemAttributes/PublicationDate'), :isbn => i.get('ItemAttributes/ISBN'), :page => i.get('ItemAttributes/NumberOfPages'), :imageurl=>i.get('MediumImage/URL')} ,class: "btn btn-midium btn-primary"%>
<% end %><!--if includes?-->
</td>
</tr>
<% end %><!-- #items.each do-->
<% else %><!--if #items.present?-->
見つかりませんでした。
<% end %><!-- if #items.present?-->
☆index_controller
def index
#keyword = params[:keyword]
if #keyword.present?
Amazon::Ecs.debug = true
res = Amazon::Ecs.item_search(params[:keyword],
:search_index => 'All', :response_group => 'Medium')
#items = res.items
search_isbns = #items.map{ |isbns| isbns.get('ItemAttributes/ISBN')}
search_asins = #items.map{ |asins| asins.get('ItemAttributes/ASIN')}
#existing_groups_isbns = Group.select(:isbn).where(:isbn => search_isbns).map(&:isbn)
#existing_groups_ids = Group.where(:isbn => search_isbns).map{|g| g.id}
end
Replace
<% #group = Group.where(:isbn =>isbn) %>
with
<% #group = Group.where(:isbn =>isbn).first %>
Because you need an object where you had an ActiveRecord relation
I implemented a chat system to my app.
It refreshes the list of comments partially when after new comment was submit.
So new added comment pops up without reloading whole page.
It's working fine but the problem is, it won't make input field empty(initialize) after submit :(
How can I make it empty if it succeeded at submitting?
5 seconds Auto-refreshing will be another issue that's preventing.
So I have to care about it, too.
and If possible I want to pop up flash alert 'you cant spam' when the user tried to submit comment within 10 seconds.
Let's assume as if I'm trying to submit comment from Users#show page
views/users/show.html.erb
<%= javascript_tag do %>
jQuery(document).ready(function () {
refreshPartial();
setInterval(refreshPartial, 5000)
});
function refreshPartial() {
$.ajax({
url: "<%= show_user_path(#user) %>/refresh_part",
type: "GET",
dataType: "script",
});
}
<% end %>
......
<span id="chat">
<%= render 'users/comment' %>
</span>
<%= render 'users/comment_input' %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>PIC</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #comments.each do |comment| %>
<tr id="<%= dom_id(comment) %>">
<td><%= comment.id %></td>
<td>
<% if comment.comment_icon? %>
<ul class="thumbnails">
<%= image_tag(comment.comment_icon.url(:thumb),:height => 100, :width => 100, :style => 'border:3px double #545565;' ) %>
</ul>
<% end %>
</td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>
<%= button_to 'destroy', polymorphic_path([#user, comment]), :data => {:confirm => 'Are you sure?'}, :method => :delete, :disable_with => 'deleting...', :remote => true, :class => 'btn btn-danger' if current_user && current_user.id == comment.user_id %>
</td>
</tr>
<% end %>
</table>
<%= paginate #comments, :window => 4, :outer_window => 5, :left => 2, :right => 2 %>
views/users/_comment_input.html.erb <= This is input form!!!!!
<%=form_for(([#user, #comment]), :remote => true) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments_controller.rb
def create
commentable = #community_topic||#community||#user
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = Comment.build_from(commentable, current_user.try(:id), params[:comment][:body])
#comment.comment_icon = params[:comment][:comment_icon]
if #user
#following_users = #user.all_following(order: 'updated_at DESC')
#followed_users = #user.followers
#communities_user = #user.get_up_voted(Community).order("updated_at ASC").page(params[:page]).per(5)
elsif #community
end
last_comment = Comment.where(:user_id => current_user.id).order("updated_at").last
if last_comment && (Time.now - last_comment.updated_at) <= 10.second
flash[:notice] = "You cannot spam!"
render :template => template_for(commentable)
elsif #comment.save
#if #community_topic.empty?
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = commentable.comment_threads.build
respond_to do |format|
format.html { redirect_to [#community, commentable].uniq, :notice => "comment added!" }
format.js do
if #community.present?
render 'communities/refresh_part'
elsif #community_topic.present?
render 'community_topics/refresh_part'
elsif #user.present?
render 'users/refresh_part'
end
end
end
else
render :template => template_for(commentable)
end
end
views/users/refresh_part.js.erb
$('#chat').html("<%= j(render(:partial => 'users/comment')) %>")
Well I assume this is the "body" input you want to empty so basically, just add an id to it like this :
<%= f.text_field :body, :id => "body_input" %>
And in your views/users/refresh_part.js.erb, you can add something like :
$('#body_input').val('');
This should work only if it succeded at submitting because from what I saw, your template is rendered only if the comment is saved.