lib/anchormodel/model_mixin.rb in anchormodel-0.1.3 vs lib/anchormodel/model_mixin.rb in anchormodel-0.1.4
- old
+ new
@@ -7,90 +7,12 @@
class_attribute :anchormodel_attributes, default: {}.freeze
end
class_methods do
# Creates an attribute linking to an Anchormodel. The attribute should be
- # present in the DB and the column should be named the same as `attribute_name.`
- # @param attribute_name [String,Symbol] The name and database column of the attribute
- # @param anchormodel_class [Class] Class of the Anchormodel (omit if attribute `:foo_bar` holds a `FooBar`)
- # @param optional [Boolean] If true, a presence validation is added to the model.
- # @param model_readers [Boolean] If true, the model is given an ActiveRecord::Enum style method `my_model.my_key?` reader for each key in the anchormodel
- # @param model_writers [Boolean] If true, the model is given an ActiveRecord::Enum style method `my_model.my_key!` writer for each key in the anchormodel
- # @param model_scopes [Boolean] If true, the model is given an ActiveRecord::Enum style scope `MyModel.mykey` for each key in the anchormodel
- # @param model_methods [Boolean, NilClass] If non-nil, this mass-assigns and overrides `model_readers`, `model_writers` and `model_scopes`
- def belongs_to_anchormodel(attribute_name, anchormodel_class = nil, optional: false, model_readers: true,
- model_writers: true, model_scopes: true, model_methods: nil)
- anchormodel_class ||= attribute_name.to_s.classify.constantize
- attribute_name = attribute_name.to_sym
- attribute = Anchormodel::Attribute.new(self, attribute_name, anchormodel_class, optional)
-
- # Mass configurations if model_methods was specfied
- unless model_methods.nil?
- model_readers = model_methods
- model_writers = model_methods
- model_scopes = model_methods
- end
-
- # Register attribute
- self.anchormodel_attributes = anchormodel_attributes.merge({ attribute_name => attribute }).freeze
-
- # Add presence validation if required
- unless optional
- validates attribute_name, presence: true
- end
-
- # Make casting work
- # Define serializer/deserializer
- active_model_type_value = Anchormodel::ActiveModelTypeValue.new(attribute)
-
- # Overwrite reader to force building anchors at every retrieval
- define_method(attribute_name.to_s) do
- active_model_type_value.deserialize(read_attribute(attribute_name))
- end
-
- # Override writer to fail early when an invalid target value is specified
- define_method("#{attribute_name}=") do |new_value|
- write_attribute(attribute_name, active_model_type_value.serialize(new_value))
- end
-
- # Supply serializer and deserializer
- attribute attribute_name, active_model_type_value
-
- # Create ActiveRecord::Enum style reader directly in the model if asked to do so
- # For a model User with anchormodel Role with keys :admin and :guest, this creates user.admin? and user.guest? (returning true iff role is admin/guest)
- if model_readers
- anchormodel_class.all.each do |entry|
- if respond_to?(:"#{entry.key}?")
- fail("Anchormodel reader #{entry.key}? already defined for #{self}, add `model_readers: false` to `belongs_to_anchormodel :#{attribute_name}`.")
- end
- define_method(:"#{entry.key}?") do
- public_send(attribute_name.to_s) == entry
- end
- end
- end
-
- # Create ActiveRecord::Enum style writer directly in the model if asked to do so
- # For a model User with anchormodel Role with keys :admin and :guest, this creates user.admin! and user.guest! (setting the role to admin/guest)
- if model_writers
- anchormodel_class.all.each do |entry|
- if respond_to?(:"#{entry.key}!")
- fail("Anchormodel writer #{entry.key}! already defined for #{self}, add `model_writers: false` to `belongs_to_anchormodel :#{attribute_name}`.")
- end
- define_method(:"#{entry.key}!") do
- public_send(:"#{attribute_name}=", entry)
- end
- end
- end
-
- # Create ActiveRecord::Enum style scope directly in the model class if asked to do so
- # For a model User with anchormodel Role with keys :admin and :guest, this creates user.admin! and user.guest! (setting the role to admin/guest)
- if model_scopes
- anchormodel_class.all.each do |entry|
- if respond_to?(entry.key)
- fail("Anchormodel scope #{entry.key} already defined for #{self}, add `model_scopes: false` to `belongs_to_anchormodel :#{attribute_name}`.")
- end
- scope(entry.key, -> { where(attribute_name => entry.key) })
- end
- end
+ # present in the DB and the column should be of type String and named the same as `attribute_name`.
+ # @see Anchormodel::Util#install_methods_in_model Parameters
+ def belongs_to_anchormodel(*args, **kwargs)
+ Anchormodel::Util.install_methods_in_model(self, *args, **kwargs)
end
end
end