Rails - WillPaginate Conflict - ruby-on-rails

I'm trying to paginate the messages a group has.
class GroupsController < ApplicationController
...
def show
...
#message = #group.messages.paginate(:page => params[:page])
end
<% unless #group.messages.empty? %>
<table class="messages" summary="Messages from Group">
<tr>
<td class="messages">
<span class="content"><%= messages.content%></span>
<span class="timestamp">
Posted <%= time_ago_in_words(messages.created_at) %> ago.
</span>
</td>
</tr>
</table>
<%= will_paginate #messagess%>
<%end %>
But when I try to open my group#show page, gives me the error: undefined method 'content' for #<WillPaginate::Collection:0x31a67f0>, but the line the error gives is the line where I create a new Message, that is in the group#show page as well:
<%= f.text_area :content, :rows=>5 , :cols=>49 %>
Any ideas?

You need to loop over the messages and print each one out individually.
Controller:
def show
#messages = #group.messages.paginate(:page => params[:page])
end
View:
<% unless #messages.empty? %>
<table class="messages" summary="Messages from Group">
<% #messages.each do |message| %>
<tr>
<td class="messages">
<span class="content"><%= message.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(message.created_at) %> ago.
</span>
</td>
</tr>
<% end %>
</table>
<%= will_paginate #messagess%>
<% end %>
To prevent the error on your form you will need to pass it a single instance of a message. e.g.
form_for(Message.new) do

Related

the Ransack gem does not find the result

I am using the Ransack gem, I have a patient model, I am following the documentation, and I cannot get it to work.
I have also seen many blogs about it but nothing is working for me. Hope someone can help me
I show the code of the view and the controller
my controller:
def index
#q = Patient.ransack(params[:q])
#Patients = #q.result(distinct: true)
#pagy, #patients = pagy(current_user.patients.order(apellido: :asc), items:20)
end
my view:
<%= search_form_for #q do |f| %>
<%= f.text_field :apellido_cont, class: 'form-control' %>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
<div class="row">
<div class="col-xl-3">
<h3>Mis pacientes</h3>
</div>
<div class="col-xl-6">
<div class="form-group has-search">
<span class="fa fa-search form-control-feedback"></span>
<input type="text" class="form-control" placeholder="Buscar">
</div>
</div>
<div class="col-xl-3">
<%= link_to new_patient_path, class:'nuevo' do %>
<i class="fas fa-plus"></i> NUEVO PACIENTE
<% end %>
</div>
</div>
<div class="alertas">
<% if flash[:notice] %>
<div class="alert alert-success" role="alert"><%= flash[:notice] %></div>
<% end %>
</div>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Nombre</th>
<th scope="col">Contacto</th>
<th scope="col">Edad</th>
</tr>
</thead>
<% if #patients.each do |patient| %>
<tbody>
<tr>
<td class="datos"><%= patient.apellido %> <%= patient.nombre %></td>
<td><i class="fas fa-mobile-alt"></i> <span><% if patient.telmovil.blank? %>No hay dato<% else %><%= patient.telmovil %><% end %></span></td>
<td><%= patient.age %></td>
<td><%= link_to patient_path(patient), class:'ver' do %>
<i class="far fa-eye"></i>
<% end %></td>
</tr>
<% end.empty? %>
<h5 class="titulo">No tienes ningun paciente.</h5>
<% end %>
</tbody>
</table>
<div class="paginacion mt-3">
<%== pagy_bootstrap_nav(#pagy) if #pagy.pages > 1 %>
</div>
</div>
so I'm happy I came across this post. I have been using kaminari for years and had no idea about pagy and now I'm excited to try it!
My experience is with kaminari, so I had to google usage with pagy. It looks like to me you need to pass the entire query to the pagy method.
ie:
#pagy, #patients = pagy(Patient.ransack(params[:q]).result(distinct: true))
Hopefully that works!

How to select multiple items to delete (via checkbox) in Rails 6

I created a column of checkboxes where in users can select multiple items to delete on a table. Something like this but only a button "Bulk Delete":
Here's my code:
<%= render "shared/nav_dashboard" %>
<%= render "shared/header_dashboard" %>
<section>
<div class="container-fluid">
<!-- Page Header-->
<header>
<h1 class="h3 display">Pages</h1>
</header>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>List of Pages</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th><%= link_to "Bulk Delete", page_path(page), method: :delete, data: { confirm: "Are you sure?" }%></th>
<th>Id</th>
<th>Title</th>
<th>Summary</th>
<th>Date Created</th>
<th colspan="3">Action</th>
</tr>
</thead>
<tbody>
<% #pages.each do |page| %>
<tr>
<td><input type="checkbox" value="false"> </td>
<td scope="row"><%= page.id %></td>
<td><%= page.title %></td>
<td><%= page.body.truncate(60) %></td>
<td> <%= page.created_at.strftime("%B %d, %Y") %> </td>
<td><%= link_to "Show", page_path(page)%></td>
<td><%= link_to "Edit", edit_page_path(page)%></td>
<td><%= link_to "Delete", page_path(page), method: :delete, data: { confirm: "Are you sure?" }%></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
<%= render "shared/footer_dashboard" %>
I am wondering why it did not work?
How can I do this functionality step by step?
You could to use a form. It'll look something like this (I'm using simpleform, but this will work for every your preferred form-tag helper):
In routes.rb:
resources :pages do
collection do
delete :bulk_destroy
end
end
In your view:
<%= simple_form_for :pages, url: "/pages/bulk_destroy", method: :delete do |f| %>
<ul>
<% #pages.each do |page| %>
<li> <%= page.name %> <input type="checkbox" name="collection_ids[]" value="<%= page.id %>" /> </li>
<% end %>
</ul>
<%= f.submit %>
<% end %>
In your controller:
class PagesController < ApplicationController
def bulk_destroy
Page.where(id: params[:collection_ids]).destroy_all
end
end
Heavy-lifting taken care for you: https://github.com/joshmn/active_action or check out the bare-minimum proof of concept at https://github.com/joshmn/bulk_actions_poc
if you don't prefer to write other separate method then you can try like below, you just need to be sure that when multiple ids are selected it should send as params[:ids] rather then params[:id]
def destroy
ids = params[:ids].present? ? params[:ids] : [parmas[:id]]
Pages.where(id: ids).destroy
end
you might need to change syntax based on you jquery version
$('#bulk_delete').on('click', function(e){
var selectedIds = [];
$("input[type='checkbox']:checked").each(function(e){
ids.push($(this).data('id'))
})
$.ajax({url: 'your action url',type: 'DELETE', data: {ids: selectedIds}})
})

undefined method `total_pages' for #<Review:0x007fe460871f08>

The error output is:
undefined method `total_pages' for #<Review:0x007fe460871f08>
Movie#Show:
def show
#review = #movie.reviews.paginate(page: params[:page], per_page: 6).order('created_at DESC').build
end
I set #movie via before_filter.
My view:
<% if #movie.now_playing %>
<% if #movie.reviews.any? %>
<% #movie.reviews.each do |review| %>
<div id="each_review_container">
<span><%= link_to #movie.creator.name, user_path(#movie.creator) %> | </span>
<span id="time"><%= review.created_at.try(:strftime,'%b %d, %Y') %></span>
<p>Rating: <%= review.rating %>/10</p>
<p><%= review.content %></p>
</div>
<% end %>
<div class="digg_pagination"><%= will_paginate #review %></div>
<% else %>
<span id="review_message">No Reviews yet!</span>
<span id="add_new_review_link"><%= link_to 'Add New Review', new_movie_review_path(#movie) %></span>
<% end %>
<% else %>
<p id="review_message">You will be able to submit a review when the movie releases</p>
<% end %>
Restarted my server and I get the same error.
Been stuck on this for a while and would appreciate any assistance, thanks!
It looks like a bug, I think you want to get reviews not one review:
def show
#reviews = #movie.reviews.order('created_at DESC').paginate(page: params[:page], per_page: 6)
end
View:
<% if #movie.now_playing %>
<% if #reviews.any? %>
<% #reviews.each do |review| %>
<div id="each_review_container">
<span><%= link_to #movie.creator.name, user_path(#movie.creator) %> | </span>
<span id="time"><%= review.created_at.try(:strftime,'%b %d, %Y') %></span>
<p>Rating: <%= review.rating %>/10</p>
<p><%= review.content %></p>
</div>
<% end %>
<div class="digg_pagination"><%= will_paginate #reviews %></div>
<% else %>
<span id="review_message">No Reviews yet!</span>
<span id="add_new_review_link"><%= link_to 'Add New Review', new_movie_review_path(#movie) %></span>
<% end %>
<% else %>
<p id="review_message">You will be able to submit a review when the movie releases</p>
<% end %>
In Your view ,you are calling #movie.reviews
Why are you writing #movie.reviews in loop ?You should be using #review of action instead.It is firing query every time you call it.
#movie.reviews in your view is causing error here's guess,since it doesn't include pagination parameter and you are trying to pagination through it.

adding labels/categories to looped micropost

I am following Hartl's screencast and we are iterating through microposts and showing them in the view:
<div class="span8">
<% if #user.microposts.any? %>
<h3>Microposts (<%= #user.microposts.count %>)</h3>
<ol class="microposts">
<%= render #microposts %>
</ol>
<%= will_paginate #microposts %>
<% end %>
</div>
</div>
However I want to label each micropost (Micropost 1, Micropost 2, etc...). How can I do that?
<%= render #microposts %> renders the partial app/views/microposts/_micropost.html.erb. So it should just be a case of editing that file.
In the tutorial, I believe the micropost.html.erb file looks like:
<tr>
<td class="micropost">
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
</td>
</tr>
To add a label, you could do something like:
<tr>
<td class="micropost">
<span class="label"><%= "Micropost #{micropost.id}" %><span>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
</td>
</tr>
This will add the text 'Micropost 1', 'Micropost 2' ect above each of the microposts content
Edit
If you don't want to use ID and just want sequential numbering then you can change the code to iterate over each micropost and render them individually, passing in the count:
<% #microposts.all.each_with_index do |micropost, index| %>
<%= render micropost, locals: {index: index} %>
<% end %>
Then in your partial you can use the local variable index:
<tr>
<td class="micropost">
<span class="label"><%= "Micropost #{index}" %><span>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
</td>
</tr>

Ruby On Rails - Acts As Taggable - Change name of param: keyword

I wonder if/how to change the name of the param :keyword when using acts as taggable?
Today my url looks like this:
http://www.foo.bar/tagged?keyword=baz
I would like to change the "keyword" to another word.
controller
def tagged
#current_keyword = params[:keyword]
#tags = FeedEntry.tag_counts_on(:keyword)
#tagged_feed_entries = FeedEntry.tagged_with(params[:keyword]).order("published_at desc").paginate :page => params[:sida]
end
View:
<table class="table table-striped">
<tbody>
<% if #tags %>
<% #tagged_feed_entries.each do |feed_entry| %>
<tr>
<td>
<% today = Date.today %>
<% if (today === feed_entry.published_at.to_date) %>
<span class="label label-success">
<% else %>
<span class="label">
<% end %>
<%= format_stamp_to_date(feed_entry.published_at) %>
kl:
<%= I18n.localize(feed_entry.published_at, :format => '%H:%M') %>
</span>
</td>
<td><%= link_to feed_entry.name, feed_entry_path(feed_entry) %></td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
<%= will_paginate #tagged_feed_entries, :param_name => :sida %>
You should just be able to replace all instances of params[:keyword] to params[:whatever]. Your path then becomes http://www.foo.bar/tagged?whatever=baz.
If you have a search form, you'll have to make the relevant changes there, as well.

Resources