ActiveRecord::PreparedStatementInvalid in ArticlesController - ruby-on-rails

I am trying to make an mini blog with Ruby on Rails. I have encountered this error when I wanted to add search action on articles_controller.rb. Search form is located at navbar. If the search form is blank, there is no error. If I typed something in the search form, this error,wrong number of bind variables (2 for 1) in: text LIKE ? or title LIKE appears.
error log
Started GET "/articles/search?utf8=%E2%9C%93&search=kawaii&commit=Search" for 127.0.0.1 at 2019-02-21 13:21:02 +0900
(0.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
↳ /Users/igarashinobuo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98
Processing by ArticlesController#search as HTML
Parameters: {"utf8"=>"✓", "search"=>"kawaii", "commit"=>"Search"}
Completed 500 Internal Server Error in 14ms (ActiveRecord: 0.0ms)
ActiveRecord::PreparedStatementInvalid (wrong number of bind variables (2 for 1) in: text LIKE ? or title LIKE):
app/models/article.rb:8:in search'
app/controllers/articles_controller.rb:23:insearch'
controllers/articles_controller.rb
def search
if params[:search].blank?
#articles = Article.all
else
#articles = Article.search(params)
end
end
models/article.rb
def self.search(params)
articles = Article.where("text LIKE ? or title LIKE", "%#
{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
articles
end
end
views/articles/search.html.erb
<div class="row">
<div class="col"></div>
<div class="col-md-10">
<h1>
記事リスト</h1>
<p>
<%= link_to '新規記事作成', new_article_path, class:'btn btn-lg btn-info' %>
</p>
<table class="table table-hover table-striped table-responsive-xs table-info">
<thead>
<tr>
<th>Title</th>
<th>Text</th>
<th colspan="3">Editing Options</th>
</tr>
</thead>
<tbody>
<% #articles.each do |article| %>
<tr>
<td>
<%= article.title %>
</td>
<td>
<%= truncate(article.text, length: 75) %>
</td>
<td>
<%= link_to 'SHOW', article_path(article), class: 'btn btn-sm btn-info' %>
</td>
<td>
<%= link_to 'Edit', edit_article_path(article), class: 'btn btn-sm btn-warning' %>
</td>
<td>
<%= link_to 'Delete',article_path(article), class: 'btn btn-sm btn-danger', method: :Delete, data: {confirm: '本当に削除しますか ?'} %>
</td>
</tr>
<% end %>
</tbody>
</table>
<p>
<%= link_to 'Home', welcome_index_path, class: 'btn btn-sm btn-info' %>
</p>
</div>
<div class="col"></div>
</div>

I think you're missing an ? for the second parameter of your query:
def self.search(params)
articles = Article.where("text LIKE ? or title LIKE ?", "%#
{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
articles
end

Related

Search data by first_name and last_name

I am trying to search the data that comes from two different models via another raport model. I need to filter the data listed in the index view by the user's first and last name.
##How can I search and display only the filtered data in data_filter.html.erb view?
## in raports/index.html.erb:
<div>
<div class="" id="pro_content">
<div class="main_container">
<p id="notice"><%= notice %></p>
<h1>Raports </h1>
<hr>
<%= button_to "Filter the data", {:controller => 'raports',:action=>'data_filter'},class: "btn btn-primary kerkes1", :method => "get" %>
<table class="table ">
<thead>
<tr>
<th>User</th>
<th>Vacation type</th>
<th>Start Data</th>
<th>End Data</th>
<th>Ditet</th>
<td>status</td>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #vacation_requests.each do |vacation_request| %>
<tr class="<%= vacation_request.request_level%>">
<td>
<% #home.each do |u|%>
<% if u.id == vacation_request.user_id%>
<%= u.first_name + " "+ u.last_name%>
<%end%>
<%end%>
</td>
<td>
<% #v_r.each do |vr|%>
<%if vr.id == vacation_request.vacation_type_id %>
<%= vr.vacation_type%>
<% end end%>
</td>
<td><%= vacation_request.start_data %> </td>
<td><%= vacation_request.end_data %></td>
<td>
<%=vacation_request.skip_holidays%>
</td>
<% if vacation_request.request_level == "accepted"%>
<td style = "color: green"><i class="fa fa-check"></td>
<%elsif vacation_request.request_level == "rejected" %>
<td style = "color: red"><i class="fa fa-times"></i></td>
<%else%>
<td style = "color: #daa520"><i class="fa fa-hourglass-half"></td>
<%end%>
<!-- <td><%= vacation_request.description %></td> -->
<td><%= link_to 'Show', vacation_request %></td>
<td><%= link_to 'Destroy', vacation_request, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<!-- <td><%= link_to 'Edit', edit_vacation_request_path(vacation_request) %></td>
<td><%= link_to 'Destroy', vacation_request, method: :delete, data: { confirm: 'Are you sure?' } %></td> -->
</tr>
<% end %>
</tbody>
</table>
<br>
<p>
Shiko ne formatin Excel: <br>
<%= button_to "Excel ",raports_path(format: "xls") ,class: "btn btn-primary ", :method => "get" %>
</p>
</div>
</div>
</div>
<div style="clear:both"></div>
<div style="clear:both"></div>
##In raport.rb:
def client_full_name
"#{User.first_name} #{User.last_name}"
end
def self.search_by_client_full_name(query)
where("(User.first_name || User.last_name) LIKE :q", :q => "%#{query}%")
end
In raports_controller.rb
def data_filter
#ndalo_userin = User.find(session[:user_id])
if #ndalo_userin.status.to_i == 1
redirect_to root_path
end
#home=User.all
#useri = User.find(session[:user_id])
#adminRequest =VacationRequest.where(:request_level => "to_admin")
#vacation_types = VacationType.all
#vacation_requests = VacationRequest.all
if params[:search]
#home = User.search_by_client_full_name(params[:search])
else
#home = User.all
end
# head 404 if #users.blank?
# #raport=Raport.new
end
In data_filter.html.erb
<h3>Search for vacations by fullname </h3>
<%= form_tag raports_path, :method => :get do %>
First_Name:<%= text_field_tag :first_name, params[:first_name]%>
Last_name:<%= text_field_tag :last_name, params[:last_name]%>
<%=print%>
<%= submit_tag "Search", :client_full_name => nil , :class => "btn btn-primary"%>
<%end%>
## how can i search for a certain user displayed in raports/index.html.erb even though firs_name and last_name are not saved in the report model just in user model?
You don't need User.first_name in the query. Also, you need to quote the search string.
def self.search_by_client_full_name(query)
where("first_name LIKE :q OR last_name LIKE :q ", q: "'%#{query.downcase}%'")
end
Use ILIKE or downcase the search string
def self.search_by_client_full_name(query)
where("first_name ILIKE :q OR last_name ILIKE :q ", q: "'%#{query}%'")
end
The first name and last name is only in the user.rb model
You are calling the method on User class
User.search_by_client_full_name(params[:search])
You should move the method to User model
NOTE
Also, This should be in User model
def client_full_name
"#{first_name} #{last_name}"
end

Unknown 302 Redirect happening in Rails

I'm dealing with a 302 Redirect when trying to access certain network_hosts#show pages. It's not happening on all of them. I've been trying to diagnose the issue for the last 5 hours and an befuddled.
Here's how it goes....
User clicks the following link in view network_host/index.html.erb:
<%= link_to '<i class="fa fa-eye"></i>'.html_safe, network_host_path(h.id), "data-toggle" => "tooltip", "title" => "View" %>
The controller network_host#show kicks in:
class NetworkHostsController < ApplicationController
before_action :get_company_and_locations
def show
#network_host = NetworkHost.find(params[:id])
if #network_host
#major_issues = get_host_issues(#network_host, #network_host.last_test, "major")
#minor_issues = get_host_issues(#network_host, #network_host.last_test, "minor")
end
end
end
Which accesses helper methods in helpers/application_helper.rb:
def get_company_and_locations
#company = current_user.company
#devices = Device.where(company_id: #company.id).order(name: :asc)
#locations = if #company
current_user.company_locations.order(:name)
else
[]
end
end
def get_host_issues(network_host, last_test, severity)
get_company_and_locations
# the issue_ids to remove since they are deferred
deferred_ids = []
#company.deferred_issues.each do |d|
if d.network_host_id == network_host.id && d.expires_at.future?
deferred_ids.push(d.issue_id)
end
end
# figure out the issues
results = last_test.results.select{|result| result.issue.severity == "#{severity}"}.collect{|issue| issue }
issues = results.select{ |issue| issue.issue_id
end
At this point, the network_hosts/show.html.erb view should show, but instead my log is showing a 302 Redirect:
I, [2016-10-26T18:47:52.347035 #31947] INFO -- : Started GET "/network_hosts/4673" for 12.33.233.231 at 2016-10-26 18:47:52 -0500
I, [2016-10-26T18:47:52.349154 #31947] INFO -- : Processing by NetworkHostsController#show as HTML
I, [2016-10-26T18:47:52.349218 #31947] INFO -- : Parameters: {"id"=>"4673"}
I, [2016-10-26T18:47:52.369483 #31947] INFO -- : Rendered layouts/_back_button.html.erb (0.4ms)
I, [2016-10-26T18:47:52.377738 #31947] INFO -- : Rendered network_hosts/show.html.erb within layouts/application (10.2ms)
I, [2016-10-26T18:47:52.378656 #31947] INFO -- : Redirected to https://www.myserver.com/
I, [2016-10-26T18:47:52.378816 #31947] INFO -- : Completed 302 Found in 29ms (ActiveRecord: 9.7ms)
So, at this point, I don't see any reason there would be a redirect back to my root_url, do you?
The only thing I've been able to differentiate is that the network_hosts#show displays when there are no 'minor' issues (so 1 major/1 minor issues work, or 2 major/0 minor issues), but doesn't seem to work when there are 0 major and X minor issues. Which leads me back to get_host_issues function in application_helper#get_host_issues, but from here I'm stuck.
Here is the network_host/show.html.erb (trimmed down):
<div class="table-responsive">
<table id="major_issue_table" class="table table-striped">
<thead>
<tr>
<th>Severity </th>
<th>Code </th>
<th>Problem </th>
<th><span class="nobr">Action</span></th>
</tr>
</thead>
<tbody>
<% #major_issues.to_enum.with_index(1).each do |result, index| %>
<% issue = result.issue %>
<tr>
<td><%= issue_severity(issue) %></td>
<td><%= issue.name %></td>
<td><%= truncate(issue.problem, length: 100) %></td>
<td>
<a href='#' class='deferIssue' data-toggle='modal' data-tooltip='tooltip' data-resultid='<%= result.id %>' data-issueid='<%= issue.id %>' data-target='#deferIssueModal' title='Defer'><i class='fa fa-close'></i></a>
<%= link_to '<i class="fa fa-eye"></i>'.html_safe, issue_path({id: issue.id, network_host: #network_host.id}), "data-toggle" => "tooltip", "title" => "View" %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<div class="x_content">
<div class="table-responsive">
<table id="minor_issue_table" class="table table-striped">
<thead>
<tr>
<th>Severity </th>
<th>Code </th>
<th>Problem </th>
<th><span class="nobr">Action</span></th>
</tr>
</thead>
<tbody>
<% #minor_issues.to_enum.with_index(1).each do |result, index| %>
<% issue = result %>
<tr>
<td><%= issue_severity(issue) %></td>
<td><%= issue.name %></td>
<td><%= truncate(issue.problem, length: 100) %></td>
<td>
<a href='#' class='deferIssue' data-toggle='modal' data-tooltip='tooltip' data-resultid='<%= result.id %>' data-issueid='<%= issue.id %>' data-target='#deferHostModal' title='Defer'><i class='fa fa-close'></i></a>
<i class="fa fa-close"></i>
<%= link_to '<i class="fa fa-eye"></i>'.html_safe, issue_path(issue.id), "data-toggle" => "tooltip", "title" => "View" %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
Update: Adding layouts/_back_button.html.erb
<div class="row">
<%= link_to "<span class='btn btn-default fa fa-home' style='margin-left:10px;'></span>".html_safe, :root %>
<%= link_to "<span class='btn btn-default fa fa-mail-reply'></span>".html_safe, :back %>
</div>
For major issues, you had this:
<% #major_issues.to_enum.with_index(1).each do |result, index| %>
<% issue = result.issue %>
<tr>
<td><%= issue_severity(issue) %></td>
...etc...
</tr>
<% end %>
Whereas for minor issues, you had this:
<% #minor_issues.to_enum.with_index(1).each do |result, index| %>
<% issue = result %>
<tr>
<td><%= issue_severity(issue) %></td>
...etc...
</tr>
<% end %>
Notably, in the first case you are passing an Issue object to issue_severity, whereas in the second case you are passing a Result object.
The Result object isn't going to respond to the same methods as an Issue object, so somewhere inside issue_severity, a NoMethodError is going to get raised.
The redirect almost certainly comes from a rescue_from block in ApplicationController, which catches exceptions in controller/view code and allows you to do something other than show a generic 500 error (in this case, it's probably something akin to rescue_from(Exception) { redirect_to :root }, which isn't the greatest plan; it should at least be logging the exception before redirecting, but given the logs you posted, that's not happening.

Rails 4, check_box_tag not passing ids into params hash after ajax render

My form works the way I intended it to before I filter the results in table.
The intended functionality is, allow user to select multiple objects, the selected object id's are submitted in the params hash, and accessible via params[:event_ids], when the user clicks the 'Submit' button (I've re-labeled the 'submit' button to 'swap' to clarify functionality for the user")
When I filter the results via ajax, the checkboxes and the submit button are still visible in the view, but when I click 'swap', the selected objects are not being submitted with form. I.E params[:event_ids] is not present in the params hash. I'm stumped.
Here is the code:
show.html.erb
<div class="jumbotron">
<div class="container">
<h1><%=#carpool.name%> Carpool!</h1>
<p>View carpool specific events; Send Invites and Add Events if you are the carpool manager; View a list of all members in the carpool</p>
<% if current_user == #carpool.manager %>
<p>
<a class="btn btn-primary btn-lg" href="<%=#carpool.id%>/events/new" role="button">Add Events</a>
<a class="btn btn-primary btn-lg" href="<%=#carpool.id%>/invites/new" role="button">Send Invites</a>
</p>
<% end %>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-3">
<%= render 'show_members_list' %>
</div>
<div class="col-md-9">
<%= render 'show_events_list' %>
</div>
</div>
</div>
_show_events_list.html.erb
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Drive Events</div>
<div class="panel-body">
<div class="btn-group right" role="group" aria-label="...">
<%= button_to "All Drive Events",
carpool_path(#carpool) + '?search=all',
type: "button",
remote: true,
method: :get,
class: "btn btn-default" %>
<%= button_to "I'm Driving",
carpool_path(#carpool) + '?search=my_events',
type: "button",
remote: true,
method: :get,
class: "btn btn-default"
%>
<%= button_to "I'm being Picked Up",
carpool_path(#carpool) + '?search=not_driving',
type: "button",
remote: true,
method: :get,
class: "btn btn-default"
%>
</div>
<div class="swap_button"><%= submit_tag 'Swap!', data: {confirm: "Are you sure?"}, class: "btn btn-primary btn-lg swap", id: "swap_submit" %></div>
</div>
<!-- Table -->
<table class="table">
<thead>
<tr>
<th>Who's Driving?</th>
<th>Event Name</th>
<th>Drive Event Type</th>
<th>Place</th>
<th>Game/Not Game</th>
<th>Address</th>
<th>Date</th>
<th>Swap</th>
</tr>
</thead>
<%= form_tag carpool_path(#carpool), method: :get, id: "swap_form" do %>
<tbody id="carpool_events">
<%= render 'events_list.html.erb', locals: {events: #events} %>
</tbody>
<% end %>
</table>
</div>
_events_list.html.erb
<% if #events != nil %>
<% #events.each do |event| %>
<% if event.driver_id != nil %>
<tr>
<td><%= event.driver ? event.driver.name : "swapped"%></td>
<td><%= event.name%></td>
<td><%= event.drop_off? ? "Drop Off At" : "Pick Up From" %></td>
<td><%= event.location_name%></td>
<td><%= event.is_game ? "Game" : "Not Game(event, practice)" %></td>
<td><%= event.location_address %></td>
<td><%= event.date ? event.date.strftime("%A, %d %b %Y %l:%M %p") : "Please Enter Details on TeamSnap!"%></td>
<td>
<% if current_user == event.driver %>
<%= check_box_tag "event_ids[]", event.id %>
<% end %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
show.js.erb
$("#carpool_events").html("<%= escape_javascript(render partial: 'events_list', locals: { events: #events } ) %>");
trying something like this
<%= check_box_tag "carpool[event_ids][]", event.id %>
and your console logging verify the params that will appear

Kaminari Pagination not effecting the table

I'm using kaminari gem for pagination in my rails application to paginate the categories.
I have implemented all the process, and the pagination links are also being shown. But this is not effecting the table elements list.
Index action in controller
def index
#categories = current_user.categories
#categories = Kaminari.paginate_array(#categories).page(params[:page]).per(5)
end
Index view
<h1>Categories</h1>
<div class="well">
<%= link_to "+ New Category", new_category_path, class: "btn btn-success" %>
</div>
<%= paginate #categories %>
</br>
<%= page_entries_info #categories %>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% if current_user.categories.count == 0 %>
<tr>
<td colspan="2">
No categories found. Click the button above to add a new one.
</td>
</tr>
<% else %>
<% current_user.categories.each do |category| %>
<tr>
<td><%= link_to category.name, category %></td>
<td><%= link_to "Edit", edit_category_path(category), class: "btn btn-primary" %>
<%= link_to "Delete", category, method: :delete,
data: { confirm: "You sure?" }, class: 'btn btn-small btn-danger' %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
Screenshot
As shown in the above picture it is showing all the 7 entries for a pagination of 5/page.
Can some one please explain the reason why it is not working.
I think issue is with your array type. Please try following code.
def index
#categories = current_user.categories.all
unless #categories.kind_of?(Array)
#categories = #categories.page(params[:page]).per(5)
else
#categories = Kaminari.paginate_array(#categories).page(params[:page]).per(5)
end
end
Have you tried this way? Its more optimised, only fetch those records that required.
#categories = current_user.categories.page(params[:page]).per(5)
Solution adopted from:
rails 3,Kaminari pagination for an simple Array

Layout not rendering properly as expected

In my index action I have
#posts = Post.all
This is my index.html.erb.
<div class="row">
<div class="columns large-12 small-12 medium-12">
</div>
<p id="notice"><%= notice %></p>
<h1>Listing Posts</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Body</th>
<th>Body</th>
<th>Body</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<%= #posts.each do |post| %>
<tr>
<td> <%= post.id %> </td>
<td> <%= post.title %> </td>
<td> <%= post.body %> </td>
<td > <%= link_to 'Show' %> </td>
<td > <%= link_to 'Edit', edit_post_path(post) %> </td>
<td> <%= link_to 'Destroy', post, method: :delete %> </td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to 'NEW POST', new_post_path %>
</div>
It is rendering fine except that the #posts object is printing in a form like below just above the table tag in my browser. I know it is something silly but I can't figure that out.
[#<Post id: 4, title: "new title", body: "this is new body", created_at: "2015-12-21 07:44:42", updated_at: "2015-12-21 10:31:31">, #<Post id: 7, title: "new title", body: "dfdsfd", created_at: "2015-12-21 09:40:01", updated_at: "2015-12-21 09:40:01">]
Turns out it was something really really silly! The erb template engine requires = with erb tags to display the data while the logic is written without using the =.
It was just a simple change like this:
<% #posts.each do |post| %> # without the = symbol
hai just remove the '=' in the #posts.each line.
<%#posts.each do |post| %>, thats it.
<div class="row">
<div class="columns large-12 small-12 medium-12">
</div>
<p id="notice"><%= notice %></p>
<h1>Listing Posts</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Body</th>
<th>Body</th>
<th>Body</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<% #posts.each do |post| %>
<tr>
<td> <%= post.id %> </td>
<td> <%= post.title %> </td>
<td> <%= post.body %> </td>
<td > <%= link_to 'Show' %> </td>
<td > <%= link_to 'Edit', edit_post_path(post) %> </td>
<td> <%= link_to 'Destroy', post, method: :delete %> </td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to 'NEW POST', new_post_path %>
</div>

Resources