2

I'm trying to create a mixin that allows an ActiveRecord model to act as a delegate for another model. So, doing it the typical way:

class Apple < ActiveRecord::Base
   def foo_species
      "Red delicious"
   end    
end


class AppleWrapper < ActiveRecord::Base
   belongs_to :apple
   # some meta delegation code here so that AppleWrapper 
   # has all the same interface as Apple
end


a = Apple.create
w = AppleWrapper.create
w.apple = a 
w.foo_species
# => 'Red delicious'

What I want is to abstract this behavior into a Mixin, so that given a bunch of data models, I can create "Wrapper" classes that are also ActiveRecords, but that each wrapper corresponds to a specific class. Why? Each of the data models have calculations, aggregations with other models, and I want the "Wrapper" classes to contain fields (in the schema) that correspond to these calculations...so in effect. the Wrapper acts as a cached version of the original data model, with the same interface.

I will have to write out each Wrapper...so for Apple, Orange, Pear, there is a different Wrapper model for each of them. However, I just want to abstract out the wrapper behavior...so that there's a class level method that sets what the Wrapper points to, a la:

module WrapperMixin
    extend ActiveSupport::Concern
    module ClassMethods
       def set_wrapped_class(klass)
        # this sets the relation to another data model and does the meta delegation
        end
    end
end


class AppleWrapper < ActiveRecord::Base
    include WrapperMixin
    set_wrapped_class Apple
end

class OrangeWrapper < ActiveRecord::Base
    include WrapperMixin
    set_wrapped_class Orange
end

How would I set this up? And would this have to be a STI type relation? That is, does the Wrapper class have to have a wrapped_record_id and a wrapped_record_type?

4

1 回答 1

3

您可以belongs_to在您的set_wrapped_class方法中使用。

def set_wrapped_class(klass)
  belongs_to klass.to_s.downcase.to_sym
end
于 2013-10-09T03:15:27.857 回答