I have a class similar to the following:
class FruitKinds < ActiveRecord::Base
Apple = FruitKinds.find(:all).find { |fk|
fk.fruit_name == :apple.to_s
}
# ... other fruits
# no methods
end
Apple and other specific Fruits are commonly used as default values elsewhere in my application, so I want a handy means to refer to them in an enumerable, static-ish way.
However, there’s a problem. There is a database migration to create the FruitKinds table and populate it with the special Fruits like Apple. When the database migration runs to initialize FruitKinds, rake fails to start because it first loads FruitKinds, which then makes a call to the database, which of course fails since the FruitKinds table is not yet there.
The workaround is to comment out the FruitKinds::* fields while the migration runs, but that is awful and hacky. What’s the best way to do this?
That’s a pretty common gotcha, to the point that I now consider any database access at the class definition level an antipattern. The alternative is to make it a lazy property. The simplest way to do this is simply to make it a class-level method instead of a constant. Note that you can have capitalised methods in Ruby, so you can make it look like a constant if you want:
Or if you want to get fancy you can use
const_missingto dynamically create the constant the first time it is accessed.As a side note, that’s about the most inefficient way possible to find a record by name 😉