module Sequel::Plugins::Composition::ClassMethods
Attributes
A hash with composition name keys and composition reflection hash values.
Public Instance Methods
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 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,
StringorSymbol. - :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]]}
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
Define getter and setter methods for the composition object.
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
Freeze composition information when freezing model class.