From: Gary Weaver Date: 2012-08-29T22:25:00+09:00 Subject: Re: dynamic class resolution? Ryan Davis wrote in post #1073629: > You probably want to look at const_missing. Watch out and make sure you > always call super because rails uses it to be lazy about requires. Thanks, Ryan! Looked into that more yesterday and learned about ActiveSupport::Dependencies: https://github.com/rails/rails/blob/3-2-stable/activesupport/lib/active_support/dependencies.rb It's funny after using Rails so much that I didn't give a lot of thought how class and module resolution work. So, I thought I'd try to be crafty and throw together a gem to load in Rails 3.2 that would do this (among other things): class Object class << self class << self @ref_classes={} puts "renaming const_missing to object_const_missing in #{self}" raise "Not on the right class. this is #{self.class.name}" unless instance_methods.include?(:const_missing) alias_method(:object_const_missing, :const_missing) undef_method(:const_missing) raise "didn't undefine const_missing on #{self.class.name}" if instance_methods.include?(:const_missing) raise "didn't change name of const_missing to object_const_missing on #{self.class.name}" unless instance_methods.include?(:object_const_missing) def const_missing(name) puts "in my const_missing in #{self}" return @ref_classes[name] if @ref_classes[name] if name.to_s.end_with?('Ref') orig = const_get(name.to_s.chomp('Ref')) if orig && orig.ancestors.include?(ActiveRecord::Base) ref = orig.dup ref.class_eval('include ActiveRecordRefs::Model') return ref else object_const_missing(name) end end end raise "should have been able to redefine const_missing on #{self.class.name}" unless instance_methods.include?(:const_missing) end end end So, that loads but it is completely ignored, and this morning I read this: http://wondible.com/2011/12/23/give-rails-autoloading-a-boot-to-the-head/ Getting closer. So my new goal would be to have something that allows new class "creation" via const_missing that strips off the end and does something with it, e.g. if an association has class_name: 'Person[RO,attr[first_name,last_name]]' then const_missing would take that and do a Person.dup and then pass the Person.dup class (named 'Person[RO,attr[:first_name,:last_name]]') off to a user-configurable class's class method that could do something with it like: # if the RO token is found would use the be_readonly gem's functionality new_class.class_eval('include BeReadonly::Now') # parse out attrs and do new_class.class_eval("self._accessible_attributes[:default] = #{attrs.collect{|a|a.to_sym}.inspect}") It may be too magic, but it would be a way to use associations to have each model easily define new classes and functionality to tack on to existing models, and would be a lot more DRY. The reason is because we're developing another gem that reuses mass assignment security to define attributes that are serializable to JSON, along with another custom class_attribute that specifies attributes and associations that are only serialized. -- Posted via http://www.ruby-forum.com/.