Module Sequel::Plugins::Composition::ClassMethods
In: lib/sequel/plugins/composition.rb

Methods

Attributes

compositions  [R]  A hash with composition name keys and composition reflection hash values.

Public Instance methods

Define a composition for this model, with name being the name of the composition. You must provide either a :mapping option or both the :composer and :decomposer options.

Options:

:class :if using the :mapping option, the class to use, as a Class, String or Symbol.
:composer :A proc that is instance_execed when the composition getter method is called to create the composition.
:decomposer :A proc that is instance_execed before saving the model object, if the composition object exists, which sets the columns in the model object based on the value of the composition object.
:mapping :An array where each element is either a symbol or an array of two symbols. A symbol is treated like an array of two symbols where both symbols are the same. The first symbol represents the getter method in the model, and the second symbol represents the getter method in the composition object. Example:
    # Uses columns year, month, and day in the current model
    # Uses year, month, and day methods in the composition object
    {mapping: [:year, :month, :day]}
    # Uses columns year, month, and day in the current model
    # Uses y, m, and d methods in the composition object where
    # for example y in the composition object represents year
    # in the model object.
    {mapping: [[:year, :y], [:month, :m], [:day, :d]]}

[Source]

     # File lib/sequel/plugins/composition.rb, line 94
 94:         def composition(name, opts=OPTS)
 95:           opts = opts.dup
 96:           compositions[name] = opts
 97:           if mapping = opts[:mapping]
 98:             keys = mapping.map{|k| k.is_a?(Array) ? k.first : k}
 99:             if !opts[:composer]              
100:               late_binding_class_option(opts, name)
101:               klass = opts[:class]
102:               class_proc = proc{klass || constantize(opts[:class_name])}
103:               opts[:composer] = proc do
104:                 if values = keys.map{|k| get_column_value(k)} and values.any?{|v| !v.nil?}
105:                   class_proc.call.new(*values)
106:                 else
107:                   nil
108:                 end
109:               end
110:             end
111:             if !opts[:decomposer]
112:               setter_meths = keys.map{|k| "#{k}=""#{k}="}
113:               cov_methods = mapping.map{|k| k.is_a?(Array) ? k.last : k}
114:               setters = setter_meths.zip(cov_methods)
115:               opts[:decomposer] = proc do
116:                 if (o = compositions[name]).nil?
117:                   setter_meths.each{|sm| set_column_value(sm, nil)}
118:                 else
119:                   setters.each{|sm, cm| set_column_value(sm, o.public_send(cm))}
120:                 end
121:               end
122:             end
123:           end
124:           raise(Error, "Must provide :composer and :decomposer options, or :mapping option") unless opts[:composer] && opts[:decomposer]
125:           define_composition_accessor(name, opts)
126:         end

Define getter and setter methods for the composition object.

[Source]

     # File lib/sequel/plugins/composition.rb, line 131
131:         def define_composition_accessor(name, opts=OPTS)
132:           composer = opts[:composer]
133:           @composition_module.class_eval do
134:             define_method(name) do 
135:               if compositions.has_key?(name)
136:                 compositions[name]
137:               elsif frozen?
138:                 instance_exec(&composer)
139:               else
140:                 compositions[name] = instance_exec(&composer)
141:               end
142:             end
143:             define_method("#{name}=") do |v|
144:               modified!
145:               compositions[name] = v
146:             end
147:           end
148:         end

Freeze composition information when freezing model class.

[Source]

     # File lib/sequel/plugins/composition.rb, line 151
151:         def freeze
152:           compositions.freeze.each_value(&:freeze)
153:           @composition_module.freeze
154: 
155:           super
156:         end

[Validate]