Module: Anchormodel::ModelMixin
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/anchormodel/model_mixin.rb
Overview
All Rails models making use of #belongs_to_anchormodel must include this mixin. Typically, it is included in application_record.rb
.
Class Method Summary collapse
-
.belongs_to_anchormodel(attribute_name, anchormodel_class = nil, optional: false, model_readers: true, model_writers: true, model_scopes: true, model_methods: nil) ⇒ Object
Creates an attribute linking to an Anchormodel.
Class Method Details
.belongs_to_anchormodel(attribute_name, anchormodel_class = nil, optional: false, model_readers: true, model_writers: true, model_scopes: true, model_methods: nil) ⇒ Object
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.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/anchormodel/model_mixin.rb', line 20 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 end |