Ok so I have decided to use Kaminari for pagination in a rails 3 project. I have followed the video from RailsCasts http://railscasts.com/episodes/254-pagination-with-kaminari
All goes well up until the point or running the server.
controllers/stories_controller.rb
def index
#stories = Story.all
#pages = Story.page(params[:page]).per(3)
#stories = Story.search(params[:search])
end
views/stories/index.html.erb
<%= paginate #pages %>
When i start the server the index page in question displays all the stories from the DB and renders the pagination view showing (1 2 Next > Last ยป). What am I missing to get the pagination working?
I still can not understand your code. Why do you assign Story.all to #stories in the 1st line and overwrite the variable in the 3rd line?
Anyways, #stories will display "all the stories from the DB" because you're not calling the pagination method (.per) on #stories. The pagination links will show you the paginated counts because you're calling per method on #page variable and passing it to the helper.
I mean, you need to call .per on the relation before passing it to <%= paginate %> helper.
It's quite simple.
I guess you want to get results from your search, right?
Try
#stories = Story.search(params[:search]).page(params[:page]).per(3)
and something like:
<% #stories.each do |story| %>
<%= render story %>
<% end %>
<%= paginate #stories %>
in your view
Related
I'm building a Rails app where I have individual entries called films. I would like to display the latest entry's link on the homepage (separate controller) and I'm struggling to make it work.
My films_controller.rb is as follows (excerpt):
def show
#film = Film.find(params[:id])
end
My home_controller.rb only has the following:
def index
end
And my view file (index.html.erb) has the following:
<%= link_to #film.last.filmTitle, film_path(#film) %>
I'm getting the following error:
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
With the #film.find(params[:id]) highlighted.
Thanks!
The last method:
Find the last record (or last N records if a parameter is supplied). If no order is defined it will order by primary key.
source
You can add a #last_film instance variable in your index controller and use it in the view.
def index
#films = Film.all
#last_film = Film.last
end
and in your index.html.erb
<%= link_to #last_film.filmTitle, film_path(#last_film) %>
The index method need something, currently, it didn't connect with ActiveRecord like model or table, that's why
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
So if you need to show recent posts in the index then you could something like this
def index
#films = Film.limit(10).order(created_at: :desc) #=> or you can use id
end
it will show last 10 records, for this in the index.html.erb like this
<% #films.each do |film| %>
<%= link_to film.filmTitle, film_path(film) %>
<% end %>
In the other hand if you need to show only one post which is the last then you should modify this query like this like limit(10) to limit(1) or you can use use the last method like this
def index
#film = Film.last
#or
##films = Film.limit(1).order(created_at: :desc) #=> or you can use id
end
if you use this #film = Film.last then your index file will like this
<%= link_to #film.filmTitle, film_path(#film) %>
otherwise, you need to use each method which describes before.
So i have this in my controller at the moment:
popular = Impression.select('impressionable_id, count(impressionable_id) as total').group('impressionable_id').order('total desc')
popular.each do |popevents|
#events = Event.where(id: popevents.impressionable_id)
end
Basically all this is doing is selecting the most popular events that are saved in the impressions table and getting all the event information.
So in my view i have this:
<% #events.each do |e| %>
<pre>
<%= e.eventname %>
</pre>
<% end %>
I was expecting to see around 4-5 event names here, However i'm only seeing 1. I'm guessing its because the #events is getting reset?
What would be the work around for this?
Sam
Yes, you could do something like:
#events = popular.flat_map do |popevents|
Event.where(id: popevents.impressionable_id)
end
And it would give you the full list of events. But this is very inefficient; as it is going to run a single query for each id.
A better way would be:
#events = Event.where(id: popular.map(&:impressionable_id))
which would do it all in one query.
I have a simple Rails app which has an index page that shows 59 posts.
The problem is that if I search for something, Post.count continue to show me the original number of Posts on the index page - for example if I search for a post called 'Quilon', I get a search result showing just 1 post, but the Post.count still shows the original post number which is 59.
How do I fix this?
INDEX.HTML.ERB CODE
<%= Post.count %>
SEARCH FUNCTION IN POSTS CONTROLLER
def index
#posts = Post.all
if params[:search]
#posts = #posts.search(params[:search]).order("created_at DESC")
end
if params[:zagat_status].present?
#posts = #posts.zagat_status(params[:zagat_status]).order("created_at DESC")
end
end
In your index action you narrow down the posts using some conditions, so you should operate on #posts variable, not on the model Post itself.
Which means you want to use #posts.count.
You should give <%= #posts.count %> instead of <%= Post.count %>. <%= Post.count %> returns count of all the records. It is just same as
select count(*) from "posts"
so the conditions are ignored.
Use #posts.count instead of Post.count
This code shows all the records of CommunityTopic that belongs to current Community.
How can I limit the numbers to 10 records to display here?
<ul>
<% #community.community_topics.each do |topic| %>
<li>
<%= link_to topic.title, community_topic_path(#community, topic) %>
<%= link_to topic.user.user_profile.nickname, community_topic_path(#community, topic) %>
</li>
<% end %>
</ul>
Use the limit method:
<% #community.community_topics.limit(10).each do |topic| %>
This will only supply the first 10 elements of the collection to the block. If you want to be more sophisticated, you could use something like will_paginate.
In general, such data fetching should take place in the controller. So instead of having a #community variable where the view gets the data from, have a #community_topics as well, which is prefilled with the data you want to render.
You shouldn't usually do this in the view, but rather in the controller. You can use limit as #Fermaref proposed, or you can use a paginator to help you out such as will_paginate or kaminari.
To move this to the controller, try something like this:
def some_action
#community = Community.find(params[:id])
#community_topics = #community.community_topics.order(:some_attribute).limit(10)
end
Then just use #community_topics in your view. One advantage here is that you can now move this logic to a private method for reuse if needed. You can also functionally test that #community_topics limits to 10 rows.
Use 8.3 reorder
The reorder method overrides the default scope order. For example:
#categories = Category.includes(:subcategories).where(active: true).references(:subcategories).order(name: :asc).reorder('categories.name ASC', 'subcategories.name ASC')
http://guides.rubyonrails.org/active_record_querying.html
I have a blogging application in which User has_many posts. I am using pagination with Booststrap. How can I make the partial_count method work with pagination? Currently, the count resets on every page instead of carrying over across pages.
posts_controller.rb
def index
#posts = Post.order("created_at desc").paginate(page: params[:page], :per_page => 12)
end
views/posts/index.html.erb
<%= render #posts %>
<%= will_paginate %>
views/posts/_post.html.erb
<%= post_counter +1%>
<%= post.name %>
The counter works fine on the first page. However, all subsequent pages also start with "1". How can I make subsequent pages start with (number of pages * 12 + 1) instead?
Thanks for your feedback!
Use #posts.offset to get the proper counter initialisation.