Rails: Comment Pagination under a Micropost - ruby-on-rails

I have a comment model under a micropost. I was wondering if I can paginate this so that 50 comments won't show all at once once the comment button is clicked on the micropost. I am pretty sure this cannot be paginated but is there a way that like facebook, only a certain amount shows and then the user can show more if they please. Currently my code looks like this:
Micropost HTML for the Comment Section
<div id='CommentContainer-<%= micropost.id%>' class='CommentContainer Condensed2'>
<div class='Comment'>
<%= render :partial => "comments/form", :locals => { :micropost => micropost } %>
</div>
<div id='comments'>
<%=render micropost.comments %>
</div>
</div>
When a button above is clicked it shows this section and I would not like 50 comments to show up all at once. All suggestions will be very helpful. Thank you!

Make sure you are calling #comments = Comment.paginate(:page => params[:page], :per_page => 10) in your controller
You render the group through the <%= will_paginate #comments %> call and not through :render and then later through will_paginate
Since I already know you are using nested partials. I would make sure that the item you are calling has the correct collection. After those three things are met, it should be working fine.
You can also be sure to checkout the railscast on will_paginate although without a pro subscription you may have to watch the outdated version.

I would suggest you to lookup 2 rails gems that are most widely used for pagination on rails
--> will paginate
--> Kaminari
I prefer Kaminari over will paginate because it offers a lot more flexibility than will paginate.

Related

Rails Understanding Associations Conceptually (Rendering and Posting)

I read the rails guide on associations and I have also gone through a bunch of questions here on SO and on reddit, but I am just not getting associations conceptually, I think. I have two specific issues I can use as examples from an app I am working on, but I am really just trying to understand what I am doing.
Models for these examples:
List
belongs_to :user
has_many :items
Item
belongs_to :list
belongs_to :user
User
has_many :lists
has_many :items
Issue 1: Rendering associations
I know that to show the related associations in a list I can do something like this in my view:
Users/show
<%= render #list %>
Lists/_list
<ol>
<%= list.name %>
<%= render list.items %>
</ol>
Items/_item
<li><%= item.name %></li>
This seems like magic to me. I know I am calling user.list and then list.item, but when there are multiple Lists, how does rails know to separate them with the associated Items underneath? In my head when I see this code I anticipate the following as output:
<ol>
List(a)
List(b)
List(c)
<li>item(a)</li>
<li>item(b)</li>
</ol>
What I am trying to do is render each List as a Tab and render the associated Items as the tab content. Ultimately, I have multiple different List type models I want as tabs and matching multiple different Item type models to render as tab content.
Edit: I got rid of my second issue, since the post was long and it could be a separate post. Restating the above, how can a take the above collection and render it successfully in tabs where Lists are the tabs and the associated Items render as the content?
I am running into issues if I use the code like this in my Users/show:
<div class="row">
<div class="col s12">
<ul class="tabs">
<%= render #lists %>
</ul>
</div>
<%=render #items %>
</div>
Lists/_list
<li class="tab col s3"><%= list.name%></li>
Items/_item
<div id="#tab_<%=list.id%>" class="col s12"><%= item.name %></div>
If I try this, then my item partial gives me an error, because I can’t call list.id, and it will just render all of my items without displaying them as an associated collection with the Lists. If I nest this and put everything after the <%=render lists %> inside the list partial, then the collections work, but the closing tags end up causing issues. I am not sure how to resolve this.
Passing collections to render has very little to do with associations per say - you should consult the Layouts & Rendering guide instead.
When you call render with a collection (an array of model instances) Rails creates a loop and uses the model name and conventions to find the correct partial for each member of the collection.
Rails does not care that the collection came from an association.
added:
Since the relationship between List and Item is bidirectional you can always access the list to which the item belongs by item.list:
# views/items/_item.html.erb
<div id="tab_<%= item.list.id %>" class="col s12">
<%= item.name %>
</div>
Also notice that I removed the # in the beginning of the ID since its an invalid character for an element id.

will_paginate - other queries not showing on page 2 and beyond

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>

Pagination links not showing on arrays

My app fetches the covers to each of their Facebook photo albums (I do this with Koala), and I'm trying to paginate the results with will_paginate. I have pagination working on other elements, but it doesn't seem to like working with arrays.
I've gone through the documentation, I've used require 'will_paginate/array', and I can get it to limit the amount of entries per page - I have seven albums, and will_paginate will display the first four with the below code:
albums = graph.get_connections("me", "albums")
#albums = albums.paginate(:page => params[:page], :per_page => 4)
But dropping <% will_paginate #albums %> anywhere into the view doesn't seem to affect anything, and certainly doesn't generate the pagination links. Is there something I'm missing/doing wrong?
Use <%= %> Instead of <% %>
i.e
Change
<% will_paginate #albums %>
To
<%= will_paginate #albums %>

Render in rails a view

Sorry for a simple question but i am a bit confused trying to follow ruby on rails tutorial book
I am at the chapter 10 and confused, yes i trick a bit my version for learning purpose
So I have a controller called customer
customers_controller.rb
def show
#customer = Customer.find(params[:id])
#posts = #customer.posts
end
I then have the following folder
_post.html.erb
Welcome to a post
Which his called from the show customer file has follow
/view/customer/show.html.erb
<% provide(:title, #customer.name) %>
<aside class="customer_show_nav">
<h1><%= #customer.name %></h1>
<%= #customer.email %>
</aside>
<div class="events">
<%= render #posts %>
</div>
But when loading nothing his appearing not even Welcome to a post. What i am doing wrong?
Thanks in advance. I am following the tutorial http://ruby.railstutorial.org/chapters/user-microposts#top 10.22
if _post.html.erb is in view/customers
you do this in view/customers/show.html.erb
<%= render 'controller_where_post_lives/post' %> which will look for customers/_post.html.erb
Sometimes, you also need = in <%= %> with rails 3
Also, show is used to show one item, and index is used to show all items.
So to render you will do
<%= render :partial => "post", :collection => #posts %>
Edit:
When you call render you give it the view, no objects here. Unless like above passing a collection.
http://guides.rubyonrails.org/layouts_and_rendering.html
Also if you just want to render text you can do render :text => "OK"
Look for partials explanation.

How can I change my regular filter form using a submit, to use AJAX?

I have a table of venues. The venues index page by default lists all the venue records and lets you filter them by area and or type using a form on the same page with a submit button and a page reload.
All the venues found are then displayed and the form resets itself.
How can I go about having the list of venues update without a page reload just by clicking on the differant filter options? So theres no submit button and the form keeps its altered state.
The venues controller
def index
if
#venues = Venue.with_type(params[:venuetypes]).with_area(params[:areas]).order("average_rating DESC").all
else
#venues = Venue.all
end
#venues = #venues.paginate :per_page => 15, :page => params[:page]
end
The venues index.html.erb This is already using jQuery-UI to get better looking checkboxes
<div class="filter_options_container">
<%= form_tag '', :method => :get, :id => 'filter_form' do %>
<fieldset class="filter_form_fieldset venuetypes">
<% Venuetype.all.each do |v| %>
<p class="venuetype_check"><%= check_box_tag 'venuetypes[]', v.id, false, :id => "venuetype-#{v.id}" %>
<label for="venuetype-<%= v.id %>"><%= v.name %></label></p>
<% end %>
</fieldset>
<fieldset class="filter_form_fieldset areas">
<% Area.all.each do |a| %>
<p class="area_check"><%= check_box_tag 'areas[]', a.id, false, :id => "area-#{a.id}" %>
<label for="area-<%= a.id %>"><p1><%= a.name %></p1></label></p>
<% end %>
</fieldset>
<div class="filter_form_button">
<p2><input type="submit" value="Filter"/></p2>
</div>
<% end %>
</div>
<div class="venue_partials_container">
<%= render :partial => 'venue', :collection => #venues %>
<div class="clearall"></div>
<div class="paginate_container">
<div class="paginate">
<%= will_paginate #venues %>
</div>
</div>
</div>
Thanks very much for any help its much appreciated!
You probably want to use jquery to do that.
The simplest will be to use jquery to automatically send the form when a filter is clicked, there is still a page reload but the visitor do not have to click on the submit button.
The code will be something like :
$(".checkbox-which-send-form-when-clicked").change(function(e){
$(this).parents("form:first").submit();
});
Please read documentation on jquery website
Another solution which will not make the page reloaded each time a checkbox is clicked is to use Ajax request to send the form and get the result. A good tutorial could be found here
So I don't know Ruby at all, but I know the architeccture you need to implement using jQuery. First you need to setup an endpoint that will return JSON to the client. When a user creates, modifies or just plain submits the filter form you will post or get the JSON endpoint. Its your option, you can retrieve it as each field is changed by the user or just when the submit button is clicked, it is entirely up to you how interactive you want to make it.
You would use the jQuery $.ajax functions to retrieve the JSON. I reccomend either the $.post or $.get to retrieve the updated data.jQuery AJAX Shorthand functions
You can also setup a click event handler for your form submit button. It might look like this, it is important to use the e.preventDefault because this keeps the entire page from posting back.
$("form :submit").click(function(e){
e.preventDefault();
$.getJSON([your AJAX url], [data from filter], function(result){
//update table using templates
});
});
In the $getJSON callback I reccomend using the jQuery templates or some other templating merge functionality like Resig's micro templates.
I wrote a whole series of blog posts on doing exactly this sort of thing in ASP.NET. It should translate pretty well for you to Ruby, just replace the ASP.NET stuff with your Ruby server-side and you should be on your way.
My Thin ASP.NET Series

Resources