I am creating a rails web app which basically just aggregates a list of users posts and allows them to vote and comment.
I was implementing endless scrolling by following the Railscast 114 - Endless Scrolling
post, although I have run into an issue that I am unsure if it is related to the endless scrolling, or just happened at the same time.
I am using the will_paginate gem. When the page is loaded it loads "n" number of posts the will_paginate call, but then those posts are displayed n times over.
For example:
#item.order(params[:sort]).page(params[:page]).per_page(3)
Would result in the following being displayed
item1
item2
item3
item1
item2
item3
item1
item2
item3
I have the following in my index action
#items = Item.order(sort_column + ' ' + sort_direction).page(params[:page]).per_page(5)
this is my _item partial
<% #items.each do |t| %>
<div id="Post1" class="shadow">
<table>
<tr>
<td>
t.stuff....
</td>
</tr>
</table>
</div>
And this is the render call in my index
<div id='items'>
<%= render #items %>
</div>
It feels like its something simple, but I just cannot find it. Any suggestions on where to look would be much appreciated
From my comment: change
<div id='items'>
<%= render #items %>
</div>
to
<div id='items'>
<%= render 'item' %>
</div>
Former version renders item partial for each object in #items collection (where you're iterating again over each element), that's why you get n*n items.
I think it should be
Item.paginate... not Item.order... , see the will paginate guide here
Related
Hi I am trying to display last two(few) values in my index page How to do that in rails?
Here is my _index.html.erb file (rendering in new)
<table class="table table-hover">
<% PriceLog.order(price_date: :desc).each_with_index do |price_dated,index| %> // problem is here in looping
<tr>
<% #products.each do |product| %>
<td>
<%= PriceLog.where({product_id: product.id, price_date: price_dated.price_date}).last.price_date.strftime('%d-%B-%Y') %>
</td>
<td>
<%= PriceLog.where({product_id: product.id, price_date: price_dated.price_date}).last.price %>
</td>
<% end %>
</tr>
<% end %>
</table>
and in my controller
def new
#pricelog = PriceLog.new
#products = Product.all
#price = PriceLog.all
end
Updated
Here is the output I am getting like this I have three different products like Product1,Product2,Product3 and respected date and price for that
Here my values are duplicating 3 times(every time i hit submitting in form values it showing 3 times but storing once ) How should i stop duplicating and display only last few values
Any help must appreciated
Thanks
Have you tried something along the lines Model.last(2)?
You're running a loop within a loop. Your PriceLog.each_with_index loops over all your PriceLogs, and then within it your #products.each (which you have defined in the controller) loops over all your products. So each Product gets repeated once for every PriceLog.
Outside of that, you have a lot of logic in your view. It's generally frowned upon to call the model from there; that should happen either in the controller, a helper, or some custom presenter object.
In your controller instead of
#products = Product.all
change it to
#products = Product.all.order("id DESC").limit(2)
This is how my CategoriesController looks like:
class CategoriesController < ApplicationController
def index
#categories = Category.all
end
def show
#category = Category.find(params[:id])
end
end
inside my show.html.erb I wrote this to display the category name:
<h2><%= #category.name %></h2>
I also have a PagesController which I made relations with the Category
I have few Pages assigned to Category (for example category_id: 1)
When I click on the category link from my homepage:
<%= link_to "category", category_path(cat) %>
It goes to the show page which is great
How can I display on the show.html.erb all the Pages that belongs to this category that I've clicked on?
You should call the pages assosication with the category model as,
<%= #category.name %>
<h1> PAGES </h1>
<table>
<tr>
<% #category.pages.each do |page| %>
<td> <%= page.title %> </td>
<td> <%= page.content %> </td>
<% end %>
</tr>
</table>
This will do for you.
You should use includes for enhanced performance of your application. It will return all expected records from pages also and that's without firing database query again. #category.pages in ERB will not make database query. Hence, you will have efficient code.
In your show action:
def show
#category = Category.find(params[:id]).includes(:pages)
end
In show.html.erb:
<%= "Category: #{#category.name}" %>
<h1> POSTS </h1>
<table>
<tr>
<% #category.pages.each do |page| %>
<td> <%= page.field1 %> </td>
<td> <%= page.field2 %> </td>
<% end %>
</tr>
</table>
Rich Peck edit
Normally, ActiveRecord does something called lazy loading, which means that it will only execute a DB query when it needs to. This is normally highly efficient; unfortunately causes a problem when you call associative data.
When calling #category.pages, you get the n+1 issue, which means that each time you call the Category.find query, an extra query will be used to load the pages:
The above code will execute just 2 queries, as opposed to 11 queries in the previous case:
SELECT * FROM clients LIMIT 10
SELECT addresses.* FROM addresses
WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))
So using .includes essentially appends all the pages to your #category, making it much more efficient than letting it load lazily.
Well mostly it depends on how you made your relationships between category and page. With what i can see from your code, you can do something like this.
#pages = Page.where(:category_id => 1)
Update
As per to your relationships
#pages = #category.pages
I have a view that shows two Active Record queries, one of which I use will_paginate on.
All works great with will_paginate, but if I click next or page 2, the second query is not longer rendered on the view.
I probably don't understand the flow of will_paginate processing, so any help is appreciated. In particular, why is will_paginate affecting the other, unrelated query from showing in the view? If I click on the first page, the 2nd query shows up again in the view. The controller returns the two queries and has the .paginate on the one query.
Thanks!
Per request, here's a summary of the code I'm asking about. I forgot to mention the other query also uses will_paginate. And therefore, I found my problem. I was using the same page parameter for both paginates! I found a good article describing what to do:
http://candidcode.com/2009/11/03/paginating-multiple-models-using-will_paginate-on-the-same-page/
And updated my code, and it works. This is basically, the correct code when you want two will_paginates on different models on the same view.
Controller:
def index
#query1 = Post.somescope.paginate(:page => params[:query1_page], :per_page => 50)
#query2 = Post.someotherscope.paginate(:page => params[:query2_page], :per_page => 20)
end
View:
<ul class="list-unstyled">
<li>
<%= will_paginate #query1, :param_name => 'query1_page' %>
</li>
<% #query1.each do |q1| %>
<li>...</li>
<% end %>
</ul>
<ul class="list-unstyled">
<li>
<%= will_paginate #query2, :param_name => 'query2_page' %>
</li>
<% #query2.each do |q2| %>
<li>...</li>
<% end %>
</ul>
I am working on a RoR WebApp. I'm trying to group results on the search page based on their taxonomy. What I want to do is to show a header for a category and list all results under that category. Something like:
CAT 1
products
CAT2
products
CAT3
.
.
I am trying using the following code:
<% if products.any? %> #products is the list of search results
<%= render :partial=> 'product_listing_feature', :locals => {:scope => scope, :scope_type => scope_type} %>
<div id="ql_product"></div>
<div class="product_rows">
<%taxons.each do |taxon|%> # taxons contains the list of unique categories in products
<div class = "product_row">
<h1><%=taxon%></h1>
<% taxonProducts = Array.new %>
<% products.each do |product| %>
<%#ptaxon = product.get_taxonomy%>
<%if #ptaxon == taxon%>
<% taxonProducts.push(product) %>
<% end %>
<% end %>
<div class ="featured_product_list">
<ul class = "featured_products">
<div class = "page">
<%= render :partial=> 'product_listing', :locals=>{:collection=> taxonProducts} %>
</div>
</ul>
</div>
</div>
<% end %>
</div>
<% end %>
Surprisingly it starts the 2nd category from a new row, but the following categories appeared jumbled up, something like
CAT1
products
CAT2
products CAT3
products
picture would give a better idea.
I am really surprised why it works only for one iteration. Could someone please help me fix this.
Thanks a lot
Way, way too much logic for a view. Just use group_by in your controller, which will give you a mapping of names to arrays of products:
products = Product.includes(:taxon).group_by { |p| p.taxon.name }
I'm pulling pictures via the Facebook API and that I'm trying to split the pictures into three columns, using twitter bootstrap and the rails koala gem.
The pictures separate into columns ok, but the spacing within the columns is very lumpy. Sometimes there will be a huge gap within a column between pictures. It seems to be because there is a much longer picture in one of the other columns.
Is there a way to make sure that pictures show up more fluidly?
Here is my code. Thank you
<div class = "row-fluid">
<div class ="span16">
<% #album = #graph.get_connections("me", "albums") %>
<% #album.each do |result| %>
<% #photos = #graph.get_connections("#{result['id']}", "photos") %>
<% #photos.each do |result| %>
<div class ="span3">
<img src="<%= result["source"] %>">
</div>
<% end %>
<% end %>
</div>
</div>
If your grid system is 16 columns (span16) and you want to display images into span3 divs you have to split them into 5elements per row, cause span3*5=span15 so your code should have a loop that count elements and each 5 close the row and opens another.