I can't render my items on view using will_paginate. I get this error
undefined method `total_pages' for #<Enumerator:0x007fe098856378>
Here is my pagination on controller
#com = #text.comments.sorted.paginate(:page => 1, :per_page => 30)
and my view file code.
<% will_paginate #com.each do |text| %>
<div class="comments"> <p class="time"><%= Time.now %></p>
<p><%= text.text %></p></div>
And the controller file is
def show
#text = Microblog.find(params[:id])
#com = #text.comments.sorted.paginate(:page => 1, :per_page => 2)
#rating = (#text.up - #text.down)
end
And the model file
class Comment < ActiveRecord::Base
attr_accessible :text, :microblog_id
belongs_to :microblog
scope :sorted, order("comments.created_at DESC")
end
I can't find what is the problem here :(
You are mixing the pagination widget (< 1 2 3 >) with the listing of your available elements. What you want is:
<% will_paginate #com %>
<% #com.each do |text| %>
<div class="comments"> <p class="time"><%= Time.now %></p>
<p><%= text.text %></p></div>
Problem solved! used :page => params[:page] instead of :page => 1
Thanks everybody
Related
I working with ruby on rails and my products views is cached and I can find products with search form. I want to use pagination as well, but when added, it didn't worked and also search form. Found code line ,but not sure how to use it, code below.
<% cache ["v1-#{params[:page]-#{params[:q]", cache_key_for_products]
> do %>
My code
Index.html.erb
<div class="products">
<div class="container">
<center><h1>All products</h1></center>
<div class="row">
<% cache(cache_key_for_products) do %>
<%= render #products %>
<% end %>
</div>
<%= will_paginate #comments, :container => false %>
</div>
</div>
_product.html.erb
<% cache product do %>
<div class="col-md-3 col-lg-3 col-sm-6 col-xs-12">
<div class="product-block">
<h4 id="product-name"><%= product.name %></h4>
<%= link_to product_path(product), class: 'product_link' do %>
<%= image_tag(product.image_url, class: "img-responsive") %>
<% end %>
<div class="price">
<h4>£ <%= product.price %></h4>
</div>
</div>
</div>
<% end %>
products_helper.rb
module ProductsHelper
def cache_key_for_products
count = Product.count
max_updated_at = Product.maximum(:updated_at).try(:utc).try(:to_s, :number)
"products/#{params[:q] || "all"}-#{count}-#{max_updated_at}#{signed_in? && current_user.admin? ? "-admin" : "normal"}"
end
end
products_controller.rb
def index
if params[:q].present?
search_term = params[:q]
if Rails.env.development?
#products = Product.where("name LIKE ?", "%#{search_term}%")
else
#products = Product.where("name ilike ?", "%#{search_term}%")
end
else
#products = Product.all.paginate(:page => params[:page], :per_page => 30)
end
end
In your controller, looks like you are paginating correctly when not performing a search, but need to add the pagination to your search query also:
def index
if params[:q].present?
search_term = params[:q]
if Rails.env.development?
#products = Product.where("name LIKE ?", "%#{search_term}%").paginate(:page => params[:page], :per_page => 30)
else
#products = Product.where("name ilike ?", "%#{search_term}%").paginate(:page => params[:page], :per_page => 30)
end
else
#products = Product.all.paginate(:page => params[:page], :per_page => 30)
end
end
Also you are caching each search result set, this means that the same products could be potentially cached multiple times in many different searches. This will quickly bloat your cache. It would be better to cache each product once and fetch these products from cache regardless of the search.
I see you are caching each product (in _product.html.erb partial). In index.html.erb change the code to this:
<div class="products">
<div class="container">
<center><h1>All products</h1></center>
<div class="row">
<%= render #products, cache: true %>
</div>
<%= will_paginate #comments, :container => false %>
</div>
</div>
This will take advantage of multi fetch fragment caching which Rails 5 has built in:
1.3.1 Collection caching
The render helper can also cache individual templates rendered for a
collection. It can even one up the previous example with each by
reading all cache templates at once instead of one by one. This is
done by passing cached: true when rendering the collection:
<%= render partial: 'products/product', collection: #products, cached:
true %> All cached templates from previous renders will be fetched at
once with much greater speed. Additionally, the templates that haven't
yet been cached will be written to cache and multi fetched on the next
render.
Otherwise if you are < Rails 5, use the Multi Fetch Fragments gem to enable this functionality.
In index.html.erb you could modify the collection cache rendering to something this to use a custom cache key:
<%= render #products, cache: Proc.new{|item| [item, 'show']} %>
I'm working on a project on Ruby on rails and wanted to added a search feature. I installed the solr gem following the steps from this site:
http://es.asciicasts.com/episodes/278-busquedas-con-sunspot
right now, this is how my controller looks like:
class DealsController < ApplicationController
def index
# #deals = Deal.paginate(page: params[:page])
#search = Deal.search do
fulltext params[:search]
end
#deals = #search.results
end
private
def deal_params
params.require(:deal).permit(:title)
end
end
this is my model:
class Deal < ActiveRecord::Base
searchable do
text :title, :info1, :page
end
end
and this is my view:
<div class='container'>
<div class='row upper_container'>
<div class='search_container'>
<%= form_tag deals_path, :method => :get, :class => 'navbar-form navbar-left' do %>
<div class='form-group'>
<%= text_field_tag :search, params[:search], class: 'form-control' %>
</div>
<%= submit_tag 'Search', :name => nil %>
<% end %>
</div>
</div>
<% #deals.each_with_index do |d, i| %>
<% if i % 3 == 0 %>
<div class='row middle_container'>
<% end %>
<div class='col-md-4'>
<div class='deal_container'>
<%= d.title %>
<img src='<%= d.photo %>'>
</div>
</div>
<% if (i % 3 == 2) || (i == (#deals.length - 1)) %>
</div>
<% end %>
<% end %>
<div class='text-center'>
<%= will_paginate #deals %>
</div>
</div>
But i get the following error:
undefined method `results' for Ransack::Search>:Ransack::Search
on this line: #deals = #search.results
Any help? thanks!
Jude, change your
#deals = #search.results
to
#deals = #search.result
Are you by chance using the sunspot gem?
If you are using Active Admin and the Sunspot gem for Rails, beware:
they conflict on the search method leading to some very confusing
results.
Active Admin has a dependency on meta_search which provides a
.search() method on Active Record classes. Sunspot attempts to provide
the same method, aliased from solr_search, but only if the method does
not already exist.
In short, searching can be done using solr_search() rather than
search():
#search = Profile.solr_search do
keywords params[:q]
paginate page: params[:page], per_page: page_size
end
#results = #search.results
http://mrdanadams.com/2012/beware-using-active_admin-and-sunspot-rails-gems-together/
I created a view that show all my invoices products and also created a link that remove an invoice product from a div and it will be updated so everytime that I remove everything will be in the same page.
Here is the table
invoices
|id| |name|
1 ABC
2 DEF
invoice_products
|id| |invoice_id| |word|
1 1 AAAA
2 1 BBBB
3 2 CCCC
4 2 DDDD
Here is the controller:
def show
#invoice= Invoice.find(params[:id])
end
def destroy_job
#job = InvoiceProduct.find(params[:id])
#invoice = #job.invoice
#job.destroy()
render :partial=>"finance_management/invoice/partials/new_subjects" }
end
Here is the model
class Invoice < ActiveRecord::Base
has_many :invoice_products
end
class InvoiceProduct < ActiveRecord::Base
belongs_to :invoice
end
Here is the view: "show.html.erb"
<%= #invoice.id %>
<div id="table"%>
<% #invoice.invoice_products.each do |i| %>
<%= i.name %>
<%= i.word %>
<%=link_to_remote(image_tag("image.png"), :update => "table",:url => { :controller=>'finance_management/invoice_product',:action => 'destroy_job',:id=>i.id } )%>
<% end %>
</div>
The log:
ActionView::TemplateError (undefined method `invoice_products' for nil:NilClass)
I created "delete_job.js.erb":
$('table').html("<%= j(render partial: 'finance_management/invoice/partials/new_subjects') %>");
But I got this error:
NoMethodError (undefined method `invoice_products=' for nil:NilClass):
The problem is that is not updating the div seems because getting nil error
Somebody can help me please?
According to this you must do this:
The controller invoice_controller.rb:
def show
#invoice= Invoice.find(params[:id])
#products = InvoiceProduct.find(:all,:conditions=>['invoice_id = ?',params[:id] ])
end
def destroy_job
#job = InvoiceProduct.find(params[:id])
#obj_invoice = Invoice.find(#job.invoice_id)
#job.destroy
end
The view "invoice/show.html.erb"
<%= #invoice.id %>
<div id="table"%>
<%= render :partial=>"invoice/partials/products" %>
</div>
Don't forget to create the partial view "invoice/partials/_products.erb" this will replace the div
<% #products.each do |i| %>
<%= i.name %>
<%= i.word %>
<%=link_to_remote(image_tag("image.png"),:url=>{:controller=>'invoice',:action => 'destroy_job',:id=>i.id})%>
<% end %>
Finally create "invoice/destroy_job.rjs"
page.replace_html 'table', :partial=>'invoice/partials/products'
Create a file "destroy_job.js.erb" and place render method inside this file instead of calling it in controller:
$('YOUR_ID').html("<%= j(render partial: 'finance_management/invoice/partials/new_subjects') %>");
I have this code:
<% #cars.each do |car| %>
<div class="scroll-content-item ui-widget-header">
<%= link_to image_tag( car.profile_avatar.asset.url(:thumb) ), car %>
</div>
<% end %>
..which will display the number of cars that are defined in the index action:
def index
#search = Car.search(params[:search])
#cars = #search.all.paginate :page => params[:page], :per_page => 5
..so I'll have 5 images in the slider. I can't change it because I use it for the main <div>.
The question is, how do I make another statement in the controller and how do I make a reference to it in the view so that I can have more car pictures in the slider?
Thanks.
I got it.. I just add a new instance in controller like
#cars_footer = #search.all.paginate :page => params[:page], :per_page => 3
then I call it in the view with
<% #cars_footer.each do |car| %>
<div class="scroll-content-item ui-widget-header">
<%= link_to image_tag( car.profile_avatar.asset.url(:thumb) ), car %>
</div>
<% end %>
SO easy... well.. I am new in rails.
I tried the following code but it doesn't work
class BlogsController < ApplicationController
def index
##entry_pages = Paginator.new(self, Entry.count, 10, params[:page])
#entries = Entry.find(:all,
#:limit => #entry_pages.items_per_page,
#:offset => #entry_pages.current.offset,
:order => 'entries.created_at DESC',
:include => :user)
end
end
This is the blog view
<h1>Recently updated blogs</h1>
<% #entries.each do |entry| %>
<p>
<%= link_to entry.user.username, entries_url(:user_id => entry.user) %><br />
'<%= entry.title %>' was posted <%= time_ago_in_words(entry.created_at) %> ago
</p>
<% end %>
I want the items to be paginated like this:
<< [1][2][3] >>
Give the will_paginate GEM a try.
It provides all the features you need to paginate your blog entries.
I can recommend the paginating_find plugin. Here's a tutorial:
http://www.igvita.com/2006/09/10/faster-pagination-in-rails/
Looks like it's now hosted on github.com:
http://github.com/alexkwolfe/paginating_find/tree/master