Active Admin index with scope results in NoMemoryError: failed to allocate memory

323 views Asked by At

Working with Rails 4.2.6, I have this user model with a custom scope. Here is my models/user.rb:

class User < ActiveRecord::Base
  scope :active_customers, -> { patient.where.not(customer_id: nil) }

I am trying to display an index of all the active_customers using Active Admin, here is my admin/customer.rb:

ActiveAdmin.register User, as: "Customer" do
  menu priority: 8, label: proc{ I18n.t "admin.financial_report" }, parent: 'dev'
  actions :index

controller do
  def scoped_collection
    User.active_customers
  end
end

An it works locally and in staging but it crashes in production server.

I already have an index for all the patients that works perfectly in every enviroment. Here is the admin/patient.rb:

ActiveAdmin.register User, as: "Patient" do
 menu priority: 1, label: proc{ I18n.t "admin.users" }
 permit_params [:nickname, :name, :surname, :email, :password, :password_confirmation, :therapist_id, :created_by_admin, :randword, :phone, :active]
 actions :all, except: [:destroy]

 controller do
   def scoped_collection
     User.patient
   end

Logs in production doesn't display any trace of the SQL query because it seems to break before:

Started GET "admin/customers"
Processing by Admin::CustomersController#index
Completed 500 Internal Server Error

After checking the result for rake routes I can see that there is no route for "admin/customers" but it doesn't breaks locally neither staging server. Any clue about why is it happening?

In my routes.rb I have:

ActiveAdmin.routes(self)

In staging we have:

User.patient.count => 397
Benchmark.realtime { User.patient } => 0.0014501959958579391
User.active_customers.count => 99
Benchmark.realtime { User.active_customers } => 0.0016011869884096086

And in production:

User.patient.count => 27853
Benchmark.realtime { User.patient } => 0.007111124003131408
User.active_customers.count => 496
Benchmark.realtime { User.active_customers } => 0.0040691940012038685

So, although the difference of numbers between enviroments I don't think that the reason for the memory error in production is the number of users.

Also tried to use the scope that works in patient.rb in the customer.rb and it crashed:

controller do
  def scoped_collection
    User.patient
  end

After that I tried changing as:"Customer" to as:"User" and crashed again:

  ActiveAdmin.register User, as: "User" do

If the scope that works in patient.rb doesn't work in customer.rb it makes me discard the idea that the problem is caused just because a lack of memory. Pretty sure that the problem is related to the way I use the scope in the active admin or my syntax in customer.rb but I can't figure out how to fix it.

1

There are 1 answers

3
Piers C On

I would first check the SQL statements in your Rails log for anything unexpected. It's not obvious to me what is wrong, but personally I would do the scoping at the ActiveRecord model level instead of ActiveAdmin, eg:

class ActiveCustomer < User
  default_scope { where.not(customer_id: nil) }
end

ActiveAdmin.register ActiveCustomer do
  ...
end