Administrate: Issue: undefined method `per'

Created on 5 Nov 2015  Â·  21Comments  Â·  Source: thoughtbot/administrate

I am hitting this error no matter how many models I remove form my DashboardManifest when visiting localhost:3000/admin.

Currently running rails 4.2.4

The gem installed with no issues and the install ran perfectly with no issues. I chose to not configure anything until I could get the base up and running, however it looks like that is not possible. I checked to make sure all dependencies were also installed properly. Any ideas as to what could be causing this error?

method_missing - activerecord (4.2.4) lib/active_record/relation/delegation.rb

      elsif array_delegable?(method)
        to_a.public_send(method, *args, &block)
      elsif arel.respond_to?(method)
        arel.public_send(method, *args, &block)
      else
        super
      end
    end
  end
end

Most helpful comment

For the latest version (0.9.0), I had to change the following line (second line in the method) as suggested above from:
resources = Administrate::Search.new(resource_resolver, search_term).run
to:
resources = Administrate::Search.new(scoped_resource, dashboard_class, search_term).run

All 21 comments

I believe the per method is being defined by kaminari, which is a dependency of Administrate. It's used to paginate objects on index pages.

One way to debug this would be to copy this index method into your app/controllers/admin/application_controller.rb. If you remove the line with the per call, does the error go away?

Thank you for the speedy response @graysonwright --

I am running kaminari (Using kaminari 0.16.3)

Added the index method to app/controllers/admin/application_controller.rb --

  def index
     search_term = params[:search].to_s.strip
     resources = Administrate::Search.new(resource_resolver, search_term).run
     resources = order.apply(resources)
    #  resources = resources.page(params[:page]).per(records_per_page)
     page = Administrate::Page::Collection.new(dashboard, order: order)

     render locals: {
       resources: resources, #.page(params[:page]).per(records_per_page),
       search_term: search_term,
       page: page,
     }
   end

Looks like the page is going to load, though may take an hour since I am trying out Administrate as a solution on a large and active project (ex. 355,000 active users stored in my DB and millions of additional records). So figuring out why kaminari is not doing the deal seems to be the issue?

yep, looks like that's the issue. Are you using other pagination libraries in your app that might be conflicting with Kaminari?

ah, will_paginate...

Going to try the following:

Kaminari.configure do |config|
  config.page_method_name = :per_page_kaminari
end

Will report back soon.

Yep, kaminari is the better choice (IMHO), but I walked into a 7 year old rails app that is pretty firmly planted in will_paginate. Time to take a deeper dive. I will update this as to whether or not I find a work around or if I have to switch over to kaminari completely to use Administrate.

@dopudesign it might be easiest to keep using will_paginate, by replacing that line in the index method with the will_paginate equivalent, and then customizing the index page to display the will_paginate links.

Updated the index method in app/controllers/admin/application_controller.rb to:

  def index
     search_term = params[:search].to_s.strip
     resources = Administrate::Search.new(resource_resolver, search_term).run
     resources = order.apply(resources)
     resources = resources.paginate(:page => params[:page])     
     page = Administrate::Page::Collection.new(dashboard, order: order)

     render locals: {
       resources: resources.paginate(:page => params[:page]),
       search_term: search_term,
       page: page,
     }
   end

And strangely enough, the kaminari pagination links work great.... SO, issue solved. Thank you for trouble shooting with me @graysonwright

Yeah, no problem! Glad it's working out for you!

In future versions, I think we'll extract a paginate method that you can overwrite in the controller, so you won't have to override quite so much.

@graysonwright I ran into the same issue as @gentle-noah . Thanks for the discussion and solution, saved my time.

Anyone who runs into this issue at point, @gentle-noah's solution still works, but you need to add an extra line with the render locals block, like so: show_search_bar: show_search_bar?

Which would make it look like:

def index
    search_term = params[:search].to_s.strip
    resources = Administrate::Search.new(resource_resolver, search_term).run
    resources = order.apply(resources)
    resources = resources.paginate(:page => params[:page])
    page = Administrate::Page::Collection.new(dashboard, order: order)

    render locals: {
      resources: resources.paginate(:page => params[:page]),
      search_term: search_term,
      page: page,
      show_search_bar: show_search_bar?
   }
end

For the latest version (0.9.0), I had to change the following line (second line in the method) as suggested above from:
resources = Administrate::Search.new(resource_resolver, search_term).run
to:
resources = Administrate::Search.new(scoped_resource, dashboard_class, search_term).run

This is the solution that seems to work for me:

```ruby
def index
search_term = params[:search].to_s.strip
resources = Administrate::Search.new(scoped_resource, dashboard_class, search_term).run
resources = order.apply(resources)
resources = resources.paginate(:page => params[:page])
page = Administrate::Page::Collection.new(dashboard, order: order)

 render locals: {
   resources: resources.paginate(:page => params[:page]),
   search_term: search_term,
   page: page,
   show_search_bar: show_search_bar?
 }

end
````

Hope it helps

It seems — as we keep breaking this for you all — that it might be worth exploring the idea @graysonwright had about extracting the pagination. Would any of you be interested in picking up a PR for that?

@nickcharlton hi there - if you could provide some guidance on what to do please LMK and i'll hope to have a go at this. chrs

@nickcharlton

ok I had a go at this and this is what i came up with: am I on the right track?

# if people are using will_paginate then it will return accordingly. 
# if they are using kaminari then it will do that or 
# if none of the above, then it will return all the results at once.

def index
      # ........etc
      resources = paginate(resources)
      # ........
end

 def paginate(resources)
      if resources.page(params[:page]).klass.respond_to?(:per)
        return resources.page(params[:page]).per(records_per_page)
      elsif resources.page(params[:page]).klass.respond_to?(:paginate)
        return resources.page(params[:page]).paginate(records_per_page) # don't paginate if none are defined.
      else        
        return resources
      end
    end

If you are using will_paginate, add this to one of the initializers and problem should be solved

if defined?(WillPaginate) module WillPaginate module ActiveRecord module RelationMethods def per(value = nil) per_page(value) end def total_count() count end end end module CollectionMethods alias_method :num_pages, :total_pages end end end

it did not work for me

@uurcankaya thanks for your code :) . would you be able to elaborate on what your code is doing?

``ruby if defined?(WillPaginate) module WillPaginate module ActiveRecord module RelationMethods def per(value = nil) per_page(value) end def total_count() count end end end module CollectionMethods alias_method :num_pages, :total_pages end end end

This is the solution that seems to work for me:

def index
     search_term = params[:search].to_s.strip
     resources = Administrate::Search.new(scoped_resource, dashboard_class, search_term).run
     resources = order.apply(resources)
     resources = resources.paginate(:page => params[:page])     
     page = Administrate::Page::Collection.new(dashboard, order: order)

     render locals: {
       resources: resources.paginate(:page => params[:page]),
       search_term: search_term,
       page: page,
       show_search_bar: show_search_bar?
     }
end

Hope it helps

This Worked for me

I'm going to lock this issue as it has a solution and it's quite old. If anyone is still having problems, please open a new issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

conwayanderson picture conwayanderson  Â·  4Comments

kwerle picture kwerle  Â·  4Comments

drewtunney picture drewtunney  Â·  3Comments

Reedian picture Reedian  Â·  4Comments

jaykilleen picture jaykilleen  Â·  4Comments