module Sequel::Plugins::Composition::ClassMethods

  1. lib/sequel/plugins/composition.rb

Attributes

compositions [R]

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

Public Instance methods

composition(name, opts=OPTS)

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 used to define the method that the composition getter method will call to create the composition.

:decomposer

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

Define getter and setter methods for the composition object.

[show source]
    # File lib/sequel/plugins/composition.rb
134 def define_composition_accessor(name, opts=OPTS)
135   composer_meth = opts[:composer_method] = Plugins.def_sequel_method(@composition_module, "#{name}_composer", 0, &opts[:composer])
136   opts[:decomposer_method] = Plugins.def_sequel_method(@composition_module, "#{name}_decomposer", 0, &opts[:decomposer])
137   @composition_module.class_eval do
138     define_method(name) do 
139       if compositions.has_key?(name)
140         compositions[name]
141       elsif frozen?
142         # composer_meth is private
143         send(composer_meth)
144       else
145         compositions[name] = send(composer_meth)
146       end
147     end
148     alias_method(name, name)
149 
150     meth = :"#{name}="
151     define_method(meth) do |v|
152       modified!
153       compositions[name] = v
154     end
155     alias_method(meth, meth)
156   end
157 end
freeze()

Freeze composition information when freezing model class.

[show source]
    # File lib/sequel/plugins/composition.rb
160 def freeze
161   compositions.freeze.each_value(&:freeze)
162   @composition_module.freeze
163 
164   super
165 end