2

What I'd like to do is count all objects in the database. I started with something like this:

p ["TOTAL COUNT", ApplicationRecord.subclasses.sum(&:count)]

But while experimenting I found...

[5] pry(main)> ApplicationRecord.subclasses.count => 6

Which I expected to return a lot more than that. I can inspect the subclasses and find that some are missing.

Then I found....

[8] pry(main)> ActiveRecord::Base.descendants.count => 10

Which added a few more. Again I can inspect them individually, and I noticed a few were missing. Here is an example of one that is missing...

class MerchantsPrincipal < ApplicationRecord  
end

class Principal < MerchantsPrincipal 
end

How can I make sure those are also included?

8
  • Sorry ,why you need this? Maybe if you describe full business case, it help to resolve it with normal solution. Because you question is little bit strange. Commented Dec 15, 2017 at 21:21
  • Also, what you mean when said "all objects"? All domains (AR classes) or all rows in all tables in your database (all AR instanses)? Commented Dec 15, 2017 at 21:22
  • @MaxVinogradov I'm looking for all AR instances or rows in the table. I have a cucumber suite that is an absolute mess and I suspect is very slow because of using Factories that create way more objects than necessary. I want to the find the worst offenders of object creation and see if I can fix those tests first. Does that make sense? Commented Dec 15, 2017 at 21:26
  • 1
    And, I don't know what test you have, but maybe it's reasonable to mock db record-entities ? Commented Dec 15, 2017 at 21:33
  • 1
    Note that MerchantsPrincipal.count already includes Principal.count because of how STI works so descendants is not what you're looking for. Commented Dec 15, 2017 at 21:36

1 Answer 1

1

This is not the answer for your question, but a suggestion for you in order to speed up your test suite.

You can do some caching with FactoryGirl, something like this:

class RecordCache
  def self.[](key)
    all.fetch(key)
  end

  def self.register(name, object)
    all[name] = object
  end

  def self.setup!
    register :admin_user, FactoryGirl.create(:user, is_admin: true)
  end

  private

  def all
    @all ||= {}
  end
end

Then you need to call RecordCache.setup! in your test_helper.rb before running your test suite.

After that, you will be able to ask this RecordCache to provide the instance instead of making FactoryGirl create it again:

FactoryGirl.define do
  factory :post do
    # title content etc.
    user { RecordCache[:admin_user] }
  end
end

So that every time you call FactoryGirl.create(:post), it does not create another user. This brings some concerns, as the same record is cached through the app and should not be modified. But if you want a specific user for a specific context, you can still do:

FactoryGirl.create(:post, user: FactoryGirl.create(:user, :super_admin))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.