Loading models in rake task

I'm working on a rake task that loads AR models from a yaml file, which fails when I try to use a deserialized object, as its class hasn't been loaded.

I don't know beforehand exactly which classes are in the file(s), so need a way to load them dynamically, or load all the model classes.

Thanks in advance, Isak

I'm not sure this is the preferred way, but if you load config/ environment.rb you will have access to (among other things) all of your models. So, for example, assuming your task was defined in lib/ tasks/somefile.rake you could call require thusly:

require File.expand_path(File.dirname(__FILE__) + '../../../config/ environment')

-John

> I'm working on a rake task that loads AR models from a yaml file, > which fails when I try to use a deserialized object, as its class > hasn't been loaded. > > I don't know beforehand exactly which classes are in the file(s), so > need a way to load them dynamically, or load all the model classes.

I'm not sure this is the preferred way, but if you load config/ environment.rb you will have access to (among other things) all of your models. So, for example, assuming your task was defined in lib/ tasks/somefile.rake you could call require thusly:

require File.expand_path(File.dirname(__FILE__) + '../../../config/ environment')

I've made my task depend on the :environment task, which i believe takes care of this.

I can use my models, but it looks like they are loaded lazily and aren't available to YAML unless i explicitly use them beforehand.

E.g.:

# this works User.class.to_s # load the User class my_user = YAML.load(user_data) puts my_user.name

# while this throws: undefined method `name' for #<YAML::Object:0x343ed94> my_user = YAML.load(user_data) puts my_user.name

Suggestions appreciated,

Thanks, Isak

It feels kludgy, but you could explicitly load the models ahead of time:

task :preload => :environment do   # relative path assumes this is defined in a file in lib/tasks   Dir[File.dirname(__FILE__) + '/../../app/models/*.rb'].each do | file>     require file   end   ... end

Alternatively - this feels even more kludgy - you could test whether the class appears to be loaded and, if necessary, load the class and reload the YAML data:

task :dynamic => :environment do   my_user = YAML.load(user_data)   unless my_user.respond_to?(:name)     Object.const_get(my_user.class)     my_user = YAML.load(user_data)   end   ... end

-John

Perhaps a bit kludgy yes, but it seems to work fine. Thanks!

Isak