Module: CustomFields::Source
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/custom_fields/source.rb
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#apply_custom_fields_diff(name) ⇒ Object
Apply the modifications collected from the custom fields by updating all the documents of the relation.
-
#apply_custom_fields_localize_diff(name) ⇒ Object
If the localized attribute has been changed in at least one of the custom fields, we have to upgrade all the records enhanced by custom_fields in order to make the values consistent with the mongoid localize option.
-
#bump_custom_fields_version(name) ⇒ Object
When the fields have been modified and before the object is saved, we bump the version.
-
#collect_custom_fields_diff(name, fields) ⇒ Array
Collects all the modifications of the custom fields.
-
#custom_fields_for?(name) ⇒ true, false
Determines if the relation is enhanced by the custom fields.
-
#custom_fields_recipe_for(name) ⇒ Array
Returns the recipe (meaning all the rules) needed to build the custom klass.
-
#custom_fields_version(name) ⇒ Integer
Returns the number of the version for relation with custom fields.
-
#initialize_custom_fields_diff(name) ⇒ Object
Initializes the object tracking the modifications of the custom fields.
-
#klass_with_custom_fields(name) ⇒ Class
Returns the class enhanced by the custom fields.
-
#ordered_custom_fields(name) ⇒ Collection
Returns the ordered list of custom fields for a relation.
-
#refresh_metadata_with_custom_fields(name) ⇒ Object
Change the metadata of a relation enhanced by the custom fields.
- #set_attribute_localization(name) ⇒ Object
Instance Method Details
#apply_custom_fields_diff(name) ⇒ Object
Apply the modifications collected from the custom fields by updating all the documents of the relation. The update uses the power of mongodb to make it fully optimized.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/custom_fields/source.rb', line 169 def apply_custom_fields_diff(name) # puts "==> apply_custom_fields_recipes for #{name}, #{self._custom_fields_diff[name].inspect}" # DEBUG operations = self._custom_fields_diff[name] operations['$set'].merge!({ 'custom_fields_recipe.version' => custom_fields_version(name) }) collection = send(name).collection selector = send(name).criteria.selector # http://docs.mongodb.org/manual/reference/method/db.collection.update/#update-parameter # The <update> document must contain only update operator expressions. %w[set unset rename].each do |operation_name| _fields = operations.delete("$#{operation_name}") next if _fields.empty? _operation = { "$#{operation_name}" => _fields } collection.find(selector).update_many _operation end end |
#apply_custom_fields_localize_diff(name) ⇒ Object
If the localized attribute has been changed in at least one of the custom fields, we have to upgrade all the records enhanced by custom_fields in order to make the values consistent with the mongoid localize option.
Ex: post.attributes = ‘Hello world’ => post.attributes = { en: ‘Hello world’ }
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/custom_fields/source.rb', line 197 def apply_custom_fields_localize_diff(name) return if self._custom_field_localize_diff[name].empty? send(name).all.each do |record| updates = {} # puts "[apply_custom_fields_localize_diff] processing: record #{record._id} / #{self._custom_field_localize_diff[name].inspect}" # DEBUG self._custom_field_localize_diff[name].each do |changes| value = record.attributes[changes[:field]] if changes[:localized] updates[changes[:field]] = { Mongoid::Fields::I18n.locale.to_s => value } else # the other way around next if value.nil? updates[changes[:field]] = value[Mongoid::Fields::I18n.locale.to_s] end end next if updates.empty? collection = send(name).collection collection.find(record.atomic_selector).update_one({ '$set' => updates }) end end |
#bump_custom_fields_version(name) ⇒ Object
When the fields have been modified and before the object is saved, we bump the version.
88 89 90 91 |
# File 'lib/custom_fields/source.rb', line 88 def bump_custom_fields_version(name) version = custom_fields_version(name) + 1 send(:"#{name}_custom_fields_version=", version) end |
#collect_custom_fields_diff(name, fields) ⇒ Array
Collects all the modifications of the custom fields
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/custom_fields/source.rb', line 146 def collect_custom_fields_diff(name, fields) # puts "==> collect_custom_fields_diff for #{name}, #{fields.size}" # DEBUG memo = initialize_custom_fields_diff(name) fields.map do |field| field.collect_diff(memo) end # collect fields with a modified localized field fields.each do |field| if field.localized_changed? && field.persisted? self._custom_field_localize_diff[name] << { field: field.name, localized: field.localized? } end end end |
#custom_fields_for?(name) ⇒ true, false
Determines if the relation is enhanced by the custom fields
24 25 26 |
# File 'lib/custom_fields/source.rb', line 24 def custom_fields_for?(name) self.class.custom_fields_for?(name) end |
#custom_fields_recipe_for(name) ⇒ Array
Returns the recipe (meaning all the rules) needed to build the custom klass
64 65 66 67 68 69 70 71 |
# File 'lib/custom_fields/source.rb', line 64 def custom_fields_recipe_for(name) { 'name' => "#{relations[name.to_s].class_name.demodulize}#{_id}", 'rules' => ordered_custom_fields(name).map(&:to_recipe), 'version' => custom_fields_version(name), 'model_name' => relations[name.to_s].class_name.constantize.model_name.to_s } end |
#custom_fields_version(name) ⇒ Integer
Returns the number of the version for relation with custom fields
79 80 81 |
# File 'lib/custom_fields/source.rb', line 79 def custom_fields_version(name) send(:"#{name}_custom_fields_version") || 0 end |
#initialize_custom_fields_diff(name) ⇒ Object
Initializes the object tracking the modifications of the custom fields
133 134 135 136 137 138 |
# File 'lib/custom_fields/source.rb', line 133 def initialize_custom_fields_diff(name) self._custom_field_localize_diff ||= Hash.new([]) self._custom_fields_diff ||= {} self._custom_fields_diff[name] = { '$set' => {}, '$unset' => {}, '$rename' => {} } end |
#klass_with_custom_fields(name) ⇒ Class
Returns the class enhanced by the custom fields. Be careful, call this method only if the source class has been saved with success.
36 37 38 39 40 41 42 |
# File 'lib/custom_fields/source.rb', line 36 def klass_with_custom_fields(name) # Rails.logger.debug "[CustomFields] klass_with_custom_fields #{self.send(name).metadata.klass} / #{self.send(name).metadata[:old_klass]}" if defined?(Rails) # DEBUG recipe = custom_fields_recipe_for(name) = send(name)._association target = .[:original_klass] || .klass # avoid to use an already enhanced klass target.klass_with_custom_fields(recipe) end |
#ordered_custom_fields(name) ⇒ Collection
Returns the ordered list of custom fields for a relation
53 54 55 |
# File 'lib/custom_fields/source.rb', line 53 def ordered_custom_fields(name) send(:"#{name}_custom_fields").sort { |a, b| (a.position || 0) <=> (b.position || 0) } end |
#refresh_metadata_with_custom_fields(name) ⇒ Object
Change the metadata of a relation enhanced by the custom fields. In Mongoid, all the instances of a same document share the same metadata objects.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/custom_fields/source.rb', line 98 def (name) return if !persisted? || send(:"#{name}_custom_fields").blank? = send(name)._association # puts "old_metadata = #{old_metadata.klass.inspect} / #{old_metadata.object_id.inspect}" # DEBUG # puts "[CustomFields] refresh_metadata_with_custom_fields, #{name.inspect}, self = #{self.inspect}" send(name)._association = .clone.tap do || # Rails.logger.debug "[CustomFields] refresh_metadata_with_custom_fields #{metadata.klass}" if defined?(Rails) # DEBUG # backup the current klass .instance_variable_set(:@options, ..dup) .[:original_klass] ||= .klass .instance_variable_set(:@klass, klass_with_custom_fields(name)) end set_attribute_localization(name) # puts "new_metadata = #{self.send(name).metadata.klass.inspect} / #{self.send(name).metadata.object_id.inspect}" # DEBUG end |
#set_attribute_localization(name) ⇒ Object
120 121 122 123 124 125 126 |
# File 'lib/custom_fields/source.rb', line 120 def set_attribute_localization(name) klass_name = name.singularize.to_sym send(:"#{name}_custom_fields").each do |cf| I18n.backend.store_translations ::I18n.locale, { mongoid: { attributes: { klass_name => { cf.name.to_sym => cf.label } } } } end end |