Search code examples
ruby-on-railsrubyactiverecord

Defining class methods based on database content - performance


Which is more efficient/better in a Rails application:

class Foo < ApplicationRecord
  Foo.pluck(:name).each do |name|
    define_singleton_method(name) { Foo.find_by(name: name) }
  end
end

or running the code in an initializer (config/initializers/foo.rb):

Foo.pluck(:name).each do |name|
  Foo.define_singleton_method(name) { Foo.find_by(name: name) }
end

or maybe something else?

Note: Foo instances are created only once in an initializer. They are not changed by any user in the application.

I'm doing this to avoid writing

def self.bar
  find_by(name: 'bar')
end

for each Foo record.


Solution

  • Which is more efficient/better in a Rails application

    Initializer option for the same reason you mentioned in your note. Since your Foo is not expected to change, it is better to initialize them before hand as against initializing/defining it on the go every time when you call the class.

    Another good reason to avoid first option is, it is making a db call. Let's assume you have a method in that class which has nothing to do with generated methods, it would still define them and cost you a db transaction.

    First solution would be good if it would have been dynamic. I have dealt with similar cases and they work for me well.

    The only drawback I can think of with the initializers solution is the booting time of your app. If foo has large number of columns then it will add few secs in your booting time after deployment/restart. which I think is acceptable against those few secs multiplied by number of calls you make to Foo class.