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

Define getter and setter methods for the composition object.

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

Freeze composition information when freezing model class.

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