My application retrieves items from remote source something like that:
# in the controller
#items = RemoteSource(params[:page])
The #items is an array but just the part of whole collection.
And I'm trying to paginate it:
# in the view
paginate #items
Of course it doesn't work.
How I can paginate my collection in such situation?
P.S. I'm using gem kaminari
Try the Kaminari helper for this: #books = Kaminari.paginate_array(#items).page(params[:page])
Related
I am trying to create an api end point to show a list.
My snippet is
def index
render json: #business, adapter: :json_api
end
How can I do pagination for this list?. Is it possible by using only will_paginate gem?
Yes it is possible using will_paginate gem aslo, either you can use gem 'api-pagination' click here for more details,
if you dont want to use this gem then you can manually do something like this,
you can create a function for page and limit of records per page like this:
def page
params[:page] || 1
end
def limit
params[:per] || 10
end
And then when you fetch your records you can do something like this:
def index
#business = fetch_business.page(page).per(limit)
render json: #business
end
def fetch_business
#your code to retrive all business
end
And hence you can pass page number on every request which will help you to retrive the data easily.
Since i am begginner into this, comments and suggestions are welcomed.
I'm building an app which have group > posts > comments
To reduce the number of SQL requests, i'm using the includes method
# group controller
def show
#posts = #group.posts.includes(:comments)
end
Now, I would like to paginate comments. But I don't know how to use the function .paginate from the gem will_paginate
Do you have a tips for that ?
Issue with pagination inside controller
Since you want paginated comments associated with individual post, it's complicate to achieve in controller as you need to create N paginated comment object (say you have N posts).
What you can do
1.load posts as usual with included comments to reduce excess queries. But don't run paginate here
2.achieve pagination inside view only
<%= #posts.each do | post | %>
<% comments = post.comments.paginate(page: params[:page]) %>
..
...
...
<%= will_paginate comments%>
<% end %>
We have two models, areas and stores, which we want to run off the same path: www.mysite.com/the_name_of_the_thing_here
What we would like to do is go through the areas table for a match to show the area page and, if there is no match, to go through the stores table and show the store page instead. We're not quite sure where to put this logic (in the areas controller?) and how to switch controllers. Any ideas?
Thanks
I think you can use controller action for that, something like
#area = Area.find_by_name(params[:name])
#store = Store.find_by_name(params[:name])
if #area
redirect_to area_path(#area)
elsif #store
redirect_to store_path(#store)
else
redirect_to help_url
end
If you want to change content only make other controller method in which you define variable:
#thing = Area.find_by_name(params[:name]) || Store.find_by_name(params[:name])
and pass it to view
<%= thing.name %>
I'm trying to set up routes in Rails 3 that look like:
/items/:category/:name/
It's pretty easy to do a match to set this up, and then generate the URL with the following:
item_path(:category => #item.category, :name => #item.name)
But is there any way to set it up so that item_path #item and form_for #item will work automatically, so I don't have to pass the category every time?
Thanks!
Not really no. I would suggest defining a to_params (note the 's') method on Item as follows:
def to_params
{:category => category, :name => name}
end
And then calling it like so item_path(#item.to_params). If you hack things to default to this I can guarantee you'll run into situations in which you don't want it.
I have the following code in my practices controller index method:
#practices = #activity.practices.order('created_at DESC').limit(20)
Unfortunately, the limit call is not working, and #practices is returning >20 objects. I'm sure this is a simple thing to fix, but I'm not sure what I'm doing wrong. I seem to be using this method in the way prescribed in the docs..
I have tried placing the call to limit before the order call, with the same result.
UPDATE
SQL LOG:
Practice Load (1.6ms) SELECT "practices".* FROM "practices" WHERE ("practices".activity_id = 9) ORDER BY practiced_on DESC, created_at DESC LIMIT 20
However, further down the log, I found this:
Rendered practices/_practice.html.erb (216.9ms)
Activity Load (0.6ms) SELECT "activities".* FROM "activities" WHERE ("activities".user_id = 1)
Practice Load (0.8ms) SELECT "practices".* FROM "practices" WHERE ("practices".activity_id = 8) ORDER BY practiced_on DESC
CACHE (0.0ms) SELECT "practices".* FROM "practices" WHERE ("practices".activity_id = 9) ORDER BY practiced_on DESC
Which leads me to think that the partial is not accepting the correct collection. The partial is called thus:
<%= render #activity.practices %>
Any advice?
TIA
It looks like you are returning your limited collection correctly and storing it in the #practices instance variable.
However, you are rendering your partial with #activity.practices, which will trigger a lazy load of the entire unlimited practices collection, because that collection has not yet been loaded on the #activity object.
The answer
<%= render #practices %> should work.
Bonus round
Finally, if you want something a little more 'object-oriented' you could put your 'limited' query into a scope called 'recent_practices' so you could call:
<%= render :partial => 'practices', :object => #activity.recent_practices %>
The above example would use a local variable called 'recent_practices' inside the partial, rather than an instance variable.
More about ActiveRecord scopes here.