module Sequel::Plugins::Composition::ClassMethods

Attributes

compositions[R]

A hash with composition name keys and composition reflection hash values.

Public Instance Methods

composition(name, opts=OPTS) click to toggle source

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]]}
    # File lib/sequel/plugins/composition.rb
 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}="}
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_composition_accessor(name, opts=OPTS) click to toggle source

Define getter and setter methods for the composition object.

    # File lib/sequel/plugins/composition.rb
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() click to toggle source

Freeze composition information when freezing model class.

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