Module: Sequel::Plugins::Composition::ClassMethods
- Defined in:
- lib/sequel/plugins/composition.rb
Instance Attribute Summary collapse
-
#compositions ⇒ Object
readonly
A hash with composition name keys and composition reflection hash values.
Instance Method Summary collapse
-
#composition(name, opts = OPTS) ⇒ Object
Define a composition for this model, with name being the name of the composition.
-
#define_composition_accessor(name, opts = OPTS) ⇒ Object
Define getter and setter methods for the composition object.
-
#freeze ⇒ Object
Freeze composition information when freezing model class.
Instance Attribute Details
#compositions ⇒ Object (readonly)
A hash with composition name keys and composition reflection hash values.
71 72 73 |
# File 'lib/sequel/plugins/composition.rb', line 71 def compositions @compositions end |
Instance Method Details
#composition(name, opts = OPTS) ⇒ Object
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]]}
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/sequel/plugins/composition.rb', line 95 def composition(name, opts=OPTS) opts = opts.dup compositions[name] = opts if mapping = opts[:mapping] keys = mapping.map{|k| k.is_a?(Array) ? k.first : k} if !opts[:composer] late_binding_class_option(opts, name) klass = opts[:class] class_proc = proc{klass || constantize(opts[:class_name])} opts[:composer] = proc do if values = keys.map{|k| get_column_value(k)} and values.any?{|v| !v.nil?} class_proc.call.new(*values) else nil end end end if !opts[:decomposer] setter_meths = keys.map{|k| :"#{k}="} cov_methods = mapping.map{|k| k.is_a?(Array) ? k.last : k} setters = setter_meths.zip(cov_methods) opts[:decomposer] = proc do if (o = compositions[name]).nil? setter_meths.each{|sm| set_column_value(sm, nil)} else setters.each{|sm, cm| set_column_value(sm, o.public_send(cm))} end end end end raise(Error, "Must provide :composer and :decomposer options, or :mapping option") unless opts[:composer] && opts[:decomposer] define_composition_accessor(name, opts) end |
#define_composition_accessor(name, opts = OPTS) ⇒ Object
Define getter and setter methods for the composition object.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/sequel/plugins/composition.rb', line 132 def define_composition_accessor(name, opts=OPTS) composer_meth = opts[:composer_method] = Plugins.def_sequel_method(@composition_module, "#{name}_composer", 0, &opts[:composer]) opts[:decomposer_method] = Plugins.def_sequel_method(@composition_module, "#{name}_decomposer", 0, &opts[:decomposer]) @composition_module.class_eval do define_method(name) do if compositions.has_key?(name) compositions[name] elsif frozen? # composer_meth is private send(composer_meth) else compositions[name] = send(composer_meth) end end alias_method(name, name) meth = :"#{name}=" define_method(meth) do |v| modified! compositions[name] = v end alias_method(meth, meth) end end |
#freeze ⇒ Object
Freeze composition information when freezing model class.
158 159 160 161 162 163 |
# File 'lib/sequel/plugins/composition.rb', line 158 def freeze compositions.freeze.each_value(&:freeze) @composition_module.freeze super end |