Kaminari Pagination not effecting the table - ruby-on-rails

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

Related

ActiveRecord::PreparedStatementInvalid in ArticlesController

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

how to call a all checkbox ids in select/deselect all checkbox in ror application?

I am trying to add select/deselect all checkbox (I tried click the select all and delete the records(all) in my table) in my ror application. If I click the Select all checkbox, all checkboxes in the table are not selected, at the same time delete method are also not called.
Here my Controller file:
def destroy
#messages = Message.where(id: params[:message_ids])
#messages.destroy_all
respond_to do |format|
format.html { redirect_to messages_url, notice: 'Message was successfully destroyed.' }
format.json { head :no_content }
end
end
I am using jquery code in index.html.erb file itself. Here it is:
<p id="notice"><%= notice %></p>
<h1>Messages</h1>
<table>
<thead>
<tr>
<th ><%= check_box_tag "message_ids[]",class: 'selectall' %></th>
<th>Content</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<%= form_tag messages_path, method: :delete do %>
<% #messages.each do |message| %>
<tr>
<td><%= check_box_tag "message_ids[]", message.id%></td>
<td><%= message.content %></td>
<td><%= link_to 'Show', message %></td>
<td class="edititem"><%= link_to 'Edit', edit_message_path(message)%></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= submit_tag :Delete,class: 'btn' %>
</br>
<% end %>
<br>
<%= link_to 'New Message', new_message_path %>
</br>
<script>
$('#selectall').click(function(event) {
if (this.message_ids) {
$(':checkbox').attr('message_ids', true);
} else {
$(':checkbox').attr('message_ids', false);
}
});
</script>
I am a beginner, Please Help me to solve my issue....
Try something like
$(".selectall").click(function () {
$('#my-table tbody input[type="checkbox"]').prop('checked', this.checked);
});
$('.selectall').toggle(function(){
$('#my-table tbody input[type="checkbox"]').attr('checked','checked');
},function(){
$('#my-table tbody input[type="checkbox"]').removeAttr('checked');
});
1=> provide a id (id: 'select_all_messages')on which click trigger all checkbox checked.
2=> provide a common class on all checkbox of message which will be triggered on click id: select_all_messages
like =>
<table>
<thead>
<tr>
<th ><%= check_box_tag "select_all",id: 'select_all_messages' %></th>
<th>Content</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<%= form_tag messages_path, method: :delete do %>
<% #messages.each do |message| %>
<tr>
<td><%#= check_box_tag "message_ids[]", message.id, class: 'check_uncheck_message'%></td>
<td><%= check_box_tag "message_ids[]",message.id,false, class: 'check_uncheck_message'%></td>
<td><%= message.content %></td>
<td><%= link_to 'Show', message %></td>
<td class="edititem"><%= link_to 'Edit', edit_message_path(message)%></td>
</tr>
<% end %>
</tbody>
</table>
<script type="text/javascript">
$("#select_all_messages").on('click', function () {
$('.check_uncheck_message').prop('checked', this.checked);
//$('.check_uncheck_message').prop("checked", true);
});
</script>

How to setup restriction for view in a table tag?

This is code of my view file, it shows multiple columns for the table.
The restriction is working but columns are multiple.
<table class="table table-responsive">
<tr>
<th>Title</th>
<th>Description</th>
<% obj.each do |article| %>
<% if logged_in? && current_user == article.user %>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
<% end %>
<% end %>
</tr>
<% obj.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.description %></td>
<% if logged_in? && current_user == article.user %>
<td><%= link_to "Edit", edit_article_path(article), class: "btn btn-primary" %> </td>
<td><%= link_to "show", article_path(article), class: "btn btn-success" %></td>
<td><%= link_to "Delete", article_path(article), method: :delete, data: {confirm: "Are you Sure?"}, class: "btn btn-danger" %></td>
<td> <%= article.user.username if article.user %> </td>
<td> <%= time_ago_in_words(article.created_at) %> ago.</td>
<td> <%= time_ago_in_words(article.updated_at) %> ago.</td>
</tr>
<% end %>
<% end %>
</table>
<%= link_to 'Back', root_path, class: "btn btn-primary btn-lg" %>
You're printing the thead depending on the value of obj, try leaving just the second iteration, to print each tr, maybe something like:
<% if logged_in? && current_user == article.user %>
<tr>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
</tr>
<tbody>
<% obj.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.description %></td>
<% if logged_in? && current_user == article.user %>
<td><%= link_to "Edit", edit_article_path(article), class: "btn btn-primary" %> </td>
<td><%= link_to "show", article_path(article), class: "btn btn-success" %></td>
<td><%= link_to "Delete", article_path(article), method: :delete, data: {confirm: "Are you Sure?"}, class: "btn btn-danger" %></td>
<td> <%= article.user.username if article.user %> </td>
<td> <%= time_ago_in_words(article.created_at) %> ago.</td>
<td> <%= time_ago_in_words(article.updated_at) %> ago.</td>
<% end %>
</tr>
<% end %>
</tbody>
<% end %>
What I understand by your title question, you want to prevent the view of all your table . So
<% if logged_in? && current_user == article.user %>
<table class="table table-responsive">
<tr>
...
the rest of the code for show the table
....
</table>
<% end %>
This will hide the view of the whole table and It only will be shown for the article author
The problem is you're iterating each article in obj and outputting a header each time the currently logged in user is the articles user:
<% obj.each do |article| %>
<% if logged_in? && current_user == article.user %>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
<% end %>
<% end %>
You probably only want to show the header a single time if the user is logged in and is the user of any article, Ruby has a method for that, Enumerable#any?. So something like this should be what you're looking for:
<% if logged_in? && obj.any? { |article| current_user == article.user } %>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
<% end %>
This should only output one set of the headers if the user is logged in and is the author of any article on the page, instead of one set of headers per article authored.

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

will_paginate in the same page for the same instance variable but for three different displays

This is the controller I have writter for Orders.
def index
if current_user.has_role? :admin
#orders = Order.all.paginate(:page => params[:page], :per_page => 5)
elsif current_user.has_role? :customer
#orders = Order.where(:email => current_user.email).paginate(:page => params[:page], :per_page => 5)
elsif current_user.has_role? :white_label
#orders = Order.where(:performer_id => (Performer.where(:white_label_id => current_user.white_label.id))).paginate(:page => params[:page], :per_page => 5)
else
#orders = current_user.performer.orders.paginate(:page => params[:page], :per_page => 5)
end
#custom_video = CustomVideo.new
end
As you see I have used will_paginate gem to do pagination. This is the view page where I am doing pagination.
<div class="container">
<div class="span 8">
<% if current_user.has_role? :admin %>
<%role =1%>
<%elsif current_user.has_role? :performer %>
<%role =2%>
<% else %>
<%role =3%>
<% end %>
<h3>Awaiting Upload</h3>
<table id="order_table" class="table table-hover">
<thead>
<tr>
<th>id</th>
<th>Location</th>
<th>Performer</th>
<th>Duration</th>
<th>Quality</th>
<th>Delivery</th>
<th>Category</th>
<th>Description</th>
<th>Total</th>
<% if role==2 %>
<th>Select a video to upload for the order</th>
<%end %>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% #orders.each do |order| %>
<% if order.delivery_time_id=1%>
<% var1=14 %>
<% else %>
<% var1=7 %>
<% end %>
<% if !CustomVideo.find_by_order_id(order.id) and Time.now <= order.created_at.to_date + var1.days%>
<tr>
<td> <%= order.id%></td>
<td><% if order.location %>
<%= order.location.name %>
<% end %></td>
<td><% if order.performer %>
<%= order.performer.first_name %>
<% end %></td>
<td><% if order.duration %>
<%= order.duration.time %>
<% end %></td>
<td><% if order.quality %>
<%= order.quality.name %>
<% end %></td>
<td><% if order.delivery_time %>
<%= order.delivery_time.duration %>
<% end %></td>
<td><% if order.clip_category %>
<%= order.clip_category.name %>
<% end %></td>
<td><% if order.description %>
<%= order.description %>
<% end %></td>
<td><%= order.total %></td>
<% if role==2 %>
<td>
<%= simple_form_for(#custom_video, :html => { :multipart => true, :id => "fileupload" }) do |f| %>
<%= f.error_notification %>
<%= f.file_field :path%><br/><br>
<%= f.hidden_field :order_id,:value => order.id %>
<%=f.button :submit, :value=>"Save", :class=>"btn btn-success" %>
<% end %>
<script id="template-upload" type="text/x-tmpl">
<div class="upload">
{%=o.name%}
<div class="progress"><div class="bar" style="width: 0%"></div></div>
</div>
</script>
<%end%>
</td>
<td>
<% if role==1 %>
<%=form_tag({controller: "orders", action: "refund"}, method: "post") do%>
<%= hidden_field_tag(:id, order.id) %>
<%= submit_tag ("Refund"),:class => "btn btn-success download" %>
<% end %>
<% end %>
</td>
<% if can? :show, #order %>
<td><%= link_to 'Show', order %></td>
<% end %>
<% if can? :update, #order %>
<td><%= link_to 'Edit', edit_order_path(order) %></td>
<% end %>
<% if can? :destroy, #order %>
<td><%= link_to 'Destroy', order, method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
<%else %>
<% next %>
<%end %>
<% end -%>
<% end %>
<%= will_paginate #orders, :param_name => 'awaiting_orders' %>
</tbody>
</table><br/>
<h3>Completed Orders</h3>
<table class="table table-hover" id="order_table">
<thead>
<tr>
<th>id</th>
<th>Location</th>
<th>Performer</th>
<th>Duration</th>
<th>Quality</th>
<th>Delivery</th>
<th>Category</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% #orders.each do |order| %>
<% if order.delivery_time_id=1%>
<% var1=14 %>
<% else %>
<% var1=7 %>
<% end %>
<% if CustomVideo.find_by_order_id(order.id) and Time.now <= order.created_at.to_date+var1.days%>
<tr>
<td> <%= order.id%></td>
<td><%= order.location.name %></td>
<td><%= order.performer.first_name %></td>
<td><%= order.duration.time %></td>
<td><%= order.quality.name %></td>
<td><%= order.delivery_time.duration %></td>
<td><%= order.clip_category.name %></td>
<td>
<% if role==1 %>
<%=form_tag({controller: "orders", action: "refund"}, method: "post") do%>
<%= hidden_field_tag(:id, order.id) %>
<%= submit_tag ("Refund"),:class => "btn btn-success download" %>
<% end %>
<% end %>
</td>
<% if can? :show, #order %>
<td><%= link_to 'Show', order %></td>
<% end %>
<% if can? :update, #order %>
<td><%= link_to 'Edit', edit_order_path(order) %></td>
<% end %>
<% if can? :destroy, #order %>
<td><%= link_to 'Destroy', order, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<%else %>
<% next %>
<%end %>
<% end -%>
</tr>
<% end %>
<%= will_paginate #orders %>
</tbody>
</table><br/>
<h3>Expired Orders</h3>
<table class="table table-hover" id="order_table">
<thead>
<tr>
<th> id</th>
<th>Location</th>
<th>Performer</th>
<th>Duration</th>
<th>Quality</th>
<th>Delivery</th>
<th>Category</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% #orders.each do |order| %>
<% if order.delivery_time_id=1%>
<% var1=14 %>
<% else %>
<% var1=7 %>
<% end %>
<% if Time.now > order.created_at.to_date+var1.days%>
<tr>
<td> <%= order.id%></td>
<td><%= order.location.name %></td>
<td><%= order.performer.first_name %></td>
<td><%= order.duration.time %></td>
<td><%= order.quality.name %></td>
<td><%= order.delivery_time.duration %></td>
<td><%= order.clip_category.name %></td>
<% if can? :show, #order %>
<td><%= link_to 'Show', order %></td>
<% end %>
<% if can? :update, #order %>
<td><%= link_to 'Edit', edit_order_path(order) %></td>
<% end %>
<% if can? :destroy, #order %>
<td><%= link_to 'Destroy', order, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<%else %>
<% next %>
<%end %>
<% end -%>
</tr>
<% end %>
<%= will_paginate #orders %>
</tbody>
</table>
<br>
<h3>Orders Refunded</h3>
<table class="table table-hover" id="order_table">
<thead>
<tr>
<th> id</th>
<th>Location</th>
<th>Performer</th>
<th>Duration</th>
<th>Quality</th>
<th>Delivery</th>
<th>Category</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% #orders.each do |order| %>
<% if order.refunded %>
<tr>
<td> <%= order.id%></td>
<td><%= order.location.name %></td>
<td><%= order.performer.first_name %></td>
<td><%= order.duration.time %></td>
<td><%= order.quality.name %></td>
<td><%= order.delivery_time.duration %></td>
<td><%= order.clip_category.name %></td>
<% if can? :show, #order %>
<td><%= link_to 'Show', order %></td>
<% end %>
<% if can? :destroy, #order %>
<td><%= link_to 'Destroy', order, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<%else %>
<% next %>
<%end %>
<% end -%>
</tr>
<% end %>
<%= will_paginate #orders %>
</tbody>
</table>
<br>
</div>
</div>
<%# link_to 'New Order', new_order_path %>
The problem in this is that. If I click the second page for the first table, it is going to the second for the next table too. I have tried giving the :param_name => 'questions_page' suggested here. But the trouble here is that, I am not using different instance variable for the tables but the same one. How do I solve this?>
You've almost answered your own question. You need to be using separate instance variables for each table if you want them to behave separately.

Resources