Skip to content

Commit

Permalink
Update attribute_helpers.rb
Browse files Browse the repository at this point in the history
  • Loading branch information
rbamos authored Nov 29, 2023
1 parent 616be95 commit 28771b4
Showing 1 changed file with 0 additions and 55 deletions.
55 changes: 0 additions & 55 deletions lib/attribute_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,56 +1 @@
# frozen_string_literal: true

require "attribute_helpers/version"

# Provides helper functionality for ruby classes that store various
# database-unfriendly types as instance variables. It automatically serializes
# and deserializes things like classes and symbols to interact easily with both
# the database and your application code.

module AttributeHelpers
def attr_symbol(*attrs)
transform_attributes(*attrs, &:to_sym)
end

def attr_class(*attrs)
transform_attributes(*attrs) { |val| Kernel.const_get(val) }
end

# Implementation Note
# -------------------
# The transformers above all work by creating an anonymous module for each
# group of attributes that gets prepended into the class the AttributeHelpers
# module is included into. These modules need to be defined at method call
# time to avoid leaking the overrided methods into other classes this module
# is included in.
#
# This anonymous module needs to be prepended to work in ActiveRecord classes.
# This is because ActiveRecord doesn't have accessors/mutators defined until
# an instance is created, which means we need to use the prepend pattern
# because attempts to use instance_method instance_method will not find the
# method in the class context as it will not exist until it is dynamically
# created when an instance is created. Prepend works for us because it inserts
# the behavior *below* the class in the inheritance hierarchy, so we can
# access the default ActiveRecord accessors/ mutators through the use of
# super().
#
# More information here: http://stackoverflow.com/a/4471202/1103543
def transform_attributes(*attrs)
transformer = Module.new do
attrs.each do |attr|
# Overwrite the accessor.
define_method(attr) do
val = super()
val && yield(val)
end

# Overwrite the mutator.
define_method("#{attr}=") do |val|
super(val&.to_s)
end
end
end

prepend transformer
end
end

0 comments on commit 28771b4

Please sign in to comment.