module Sequel::Plugins::Composition::ClassMethods
Attributes
A hash with composition name keys and composition reflection hash values.
Public Instance Methods
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
orSymbol
. - :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 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 composition information when freezing model class.
# File lib/sequel/plugins/composition.rb 151 def freeze 152 compositions.freeze.each_value(&:freeze) 153 @composition_module.freeze 154 155 super 156 end