How do I provide a default class definition from /lib in Rails?

Viewed 30

I'm presently using a git subtree to manage a directory of classes/libraries somewhere under /lib. The idea is to share common classes and libraries from that directory between different projects that I manage. In it are default implementations of various classes, such as models, controllers, etc. The desired result is that any application I set up which has this subtree would not HAVE to define or customize the classes that come with default implementations, but can if needed.

For example, I have a default User model, and wish to include it automatically so that there is no need to define one in /app/models. The problem is that if I DO automatically include it, and then additionally define a User class in /app/models (say to add or override a method or some configs), that definition will never be included because the class already exists.

I'm attempting to take advantage of the fact that a class can be defined twice in Ruby, and it'll more or less "merge" the definitions. For example, defining a User class twice in the following way will result in a single User class with methods for both User.foo and User.bar:

class User
  def self.foo; 'foo'; end
end

class User
  def self.bar; 'bar'; end
end

The best way I've come up with to do this so far is to write code in an initializer like the following (note that the to_underscores method isn't a standard String method, it's my own):

Rails.configuration.to_prepare do
  [
    User,
    # more classes...
  ].each do |klass|
    filepath = Rails.root.join("app/models/#{klass.name.to_underscores}.rb")
    require filepath if File.exist? filepath
  end
end

I could clean this up a bit perhaps by looping through class definitions which exist in key subdirectories under /lib so I don't have to manually list out class names that can be extended/overridden in this way, but I feel like there's got to be a better way. This list will be pretty long and a little silly to try and manage, not to mention it'll be a lot trickier with classes defined in a directory structure with subdirectories. I'd like something more automatic. Any thoughts??

1 Answers

Why not use inheritance? So your User model inherits default behaviour from DefaultUser

class User < DefaultUser

end

class DefaultUser < ActiveRecord::Base

end

You can include the DefaultX classes by making a gem to import in Gemfile that has all of these default classes defined.

Related