Will_Paginate gem error undefined method "total_pages" - ruby-on-rails

The will_paginate gem isn't working after I changed a query to get followers/followed_users
How can I use will_paginate with this??
#users = #user.reverse_relationships.order("created_at DESC").collect { |r| User.find(r.follower) }
I've tried several options like:
#users = #user.reverse_relationships.order("created_at DESC").collect { |r| User.find(r.follower) }
#users = #users.paginate(:page => params[:page])
#users = #user.reverse_relationships.paginate(:page => params[:page]).order("created_at DESC").collect { |r| User.find(r.follower) }
Each time I get an error like undefined method "total_pages" or undefined method "paginate"

You should re-order your query so that you can call paginate and total_pages on an ActiveRecord::Relation instance, as will_paginate requires.
This would remove the collect which effectively turns your relation into an array.
This could be done with something like:
#relationships = #user.reverse_relationships.includes(:follower).order("created_at DESC")
And then just access the follower of each relationship in your view or whatnot.
This will also be more efficient - you won't be issuing a separate query for each follower, as your original code is doing.

Related

kaminari undefined method 'page'

I am trying to add Kaminari to my Rails app. I have included the gem and this is what my controller looks like:
def index
if params[:year]
if params[:year].size > 0
#songs = Song.where("year like ?", params[:year]).page(params[:page])
elsif params[:artist].size > 0
#songs = Song.where("artist_name like ?", params[:artist]).page(params[:page])
elsif params[:song].size > 0
#songs = Song.where("title like ?", params[:song]).page(params[:page])
end
else
#songs = Song.first(10).page(params[:page])
end
end
and then adding
<%= paginate #songs %>
in my view, the error I am getting is:
undefined method `page' for #<Array:0x007fab0455b4a8>
Not sure why this is coming up as I followed the docs step for step.
Kaminari uses paginate_array to paginate an array. 2 solutions:
First, you can use limit(10) instead of first(10):
#songs = Song.limit(10).page(params[:page])
Second, use paginate_array
#songs = Kaminari.paginate_array(Song.first(10)).page(params[:page])
I'd advise you rewrite your controller slightly. Better yet, move your filters to the model or a filter class. Look into present? for testing existence of params as that will check for nil and empty.
def index
#songs = Song
#songs = #songs.where("year like ?", params[:year]) if params[:year]
#songs = #songs.where("artist_name like ?", params[:artist]) if params[:artist]
#songs = #songs.where("title like ?", params[:song]) if params[:song]
#songs = #songs.limit(10).page(params[:page])
end
Tl;DR If you use Mongoid, use kaminari-mongoid instead of kaminari alone.
At Github it said, Kaminari supports Mongoid...so I went and installed gem 'kaminari' with the result: unknown method :page...later i found the mongoid adapter: kaminari-mongoid and that works now.

Kaminari and Sunspot undefined method page

I am trying to return all records that match a search in Kaminari and paginate the results. However, I am getting the following error:
undefined method 'page'
my controller code:
#search = Sunspot.search(Building) do
fulltext params[:search]
end
#buildings = #search.results.page(params[:page]).per(15)
I think I am just not understanding how to use Kaminari?
page is a method you can call in relation, you can do this:
#buildings = Building.where(id: #search.results.map(&:id)).page(params[:page]).per(5)

will_paginate and .sort =>

I recently got the will_paginate gem installed and it works great, but I would like it to work with the setup I currently have. Right now I show all feeds (or posts) on the same page, but they are sorted after how many people clicked on that page:
controller.rb
#t = Time.now
#h1 = #t - 1.hour
#feeds = Feed.find(:all, :order => "created_at DESC").sort { |p1, p2| p2.impressionist_count(:filter=>:all, :start_date=>#h1) <=> p1.impressionist_count(:filter=>:all, :start_date=>#h1)}
Now... I tested the paginate gem and it works fine if I do this in the controller:
controller.rb
#feeds = Feed.paginate(:per_page => 10, :page => params[:page], :order => "created_at DESC")
So I thought 1+1=2 and tried to combine the two by doing:
controller.rb
#feeds = Feed.paginate(:per_page => 10, :page=>params[:page], :order => "created_at DESC").sort { |p1, p2| p2.impressionist_count(:filter=>:all, :start_date=>#h1) <=> p1.impressionist_count(:filter=>:all, :start_date=>#h1)}
I'm not able to sort my posts and paginate them. I get an error when I try to load the page:
undefined method `total_pages' for #
I would like this to work, it would be pretty sweet :). However, if it does not work, is there any other way of doing this?
Thanks in advance!
It's because will_paginate works by default only on ActiveRecord relationships. Once you use the sort, it's converted to an array. If you want will_paginate to work with an array, you'll need to require support for it in your controller.
require 'will_paginate/array'

Some Instance Methods Are Undefined in acts_as_taggable

I am currently getting the following error on my post model which is under act_as_taggable_on for tags and channels.
undefined local variable or method `tag_list_on' for #
<ActiveRecord::Relation:0x007f9864675b48>
I seems that rails cannot detect the existence of tag_list_on or set_tag_list_on methods; however, it does detect the tagged_with method, whose source is located in the exact same module as the other files.
RubyMine can detect the existence of all of these methods fine btw.
Here is the section of code that I'm performing all of these operations on.
#posts = Post.tagged_with(params[:tags]).paginate(:page => params[:page]|| 1, :per_page => 20)
user_tags = #posts.tag_list_on(:tags)
custom_tags = user_tags - params[:tags]
#posts.set_tag_list_on(:customs, custom_tags)
#tags = #posts.tag_counts_on(:customs, :order => "count desc").limit(10)
#channels = #posts.tag_counts_on(:channels, :order => "count desc")
tagged_with is a class method of Post, added by the acts_as_taggable_on gem.
#posts in your code is an instance of ActiveRecord::Relation, not the Post class itself or any instance of it.
There is no tag_list_on instance method in ActiveRecord::Relation, hence the error.
tagged_with says it returns
...a scope of objects that are tagged with the specified tags.
tag_list_on and set_tag_list_on are instance methods of the Post class, added by the acts_as_taggable gem.
You need to call tag_list_on and set_tag_list_on for each instance of #posts
user_tags = []
#posts.each do |post|
user_tags = user_tags + post.tag_list_on(:tags)
end
custom_tags = user_tags.uniq - params[:tags]
# ...

How can I use scopes with Ransack in Rails 3?

In my Widget model I have the following:
scope :accessible_to, lambda { |user|
if user.has_role?('admin')
self.all
else
roles = user.roles
role_ids = []
roles.each { |r| role_ids << r.id }
self.joins(:widget_assignments).where('widget_assignments.role_id' => role_ids)
end
}
Ideally, I would like to use this scope as a filter for Ransack's search results, so in my controller I have:
def index
#q = Widget.accessible_to(current_user).search(params[:q])
#widgets = #q.result.order('created_at DESC')
end
Doing this generates the following error:
undefined method `search' for Array:0x007ff9b87a0300
I'm guessing that Ransack is looking for an ActiveRecord relation object and not an array. Is there anyway that I can use my scope as a filter for Ransack?
Change the self.all for self.scoped. all returns an array.
Update for Rails 4: all will now return a scope.

Resources