Skip to content

Commit

Permalink
Refactor method definition to private methods
Browse files Browse the repository at this point in the history
  • Loading branch information
shioyama committed Nov 28, 2017
1 parent cfcf97f commit 14a75a0
Showing 1 changed file with 41 additions and 34 deletions.
75 changes: 41 additions & 34 deletions lib/mobility/plugins/active_record/dirty.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,30 @@ class MethodsBuilder < ActiveModel::Dirty::MethodsBuilder
def initialize(*attribute_names)
super
@attribute_names = attribute_names
define_method_overrides
define_attribute_methods if ::ActiveRecord::VERSION::STRING >= '5.1'
end

# Overrides +ActiveRecord::AttributeMethods::ClassMethods#has_attribute+ to treat fallthrough attribute methods
# just like "real" attribute methods.
#
# @note Patching +has_attribute?+ is necessary as of AR 5.1 due to this commit[https://github.com/rails/rails/commit/4fed08fa787a316fa51f14baca9eae11913f5050].
# (I have voiced my opposition to this change here[https://github.com/rails/rails/pull/27963#issuecomment-310092787]).
# @param [Attributes] attributes
def included(model_class)
names = @attribute_names
method_name_regex = /\A(#{names.join('|'.freeze)})_([a-z]{2}(_[a-z]{2})?)(=?|\??)\z/.freeze
has_attribute = Module.new do
define_method :has_attribute? do |attr_name|
super(attr_name) || !!method_name_regex.match(attr_name)
end
end
model_class.extend has_attribute
end

private

def define_method_overrides
changes_applied_method = ::ActiveRecord::VERSION::STRING < '5.1' ? :changes_applied : :changes_internally_applied
define_method changes_applied_method do
@previously_changed = changes
Expand All @@ -45,47 +68,31 @@ def initialize(*attribute_names)
define_method :previous_changes do
(@previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new).merge(super())
end
end

if ::ActiveRecord::VERSION::STRING >= '5.1'
define_method :saved_changes do
(@previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new).merge(super())
end

attribute_names.each do |name|
define_method :"saved_change_to_#{name}?" do
previous_changes.include?(Mobility.normalize_locale_accessor(name))
end

define_method :"saved_change_to_#{name}" do
previous_changes[Mobility.normalize_locale_accessor(name)]
end
# For AR >= 5.1 only
def define_attribute_methods
define_method :saved_changes do
(@previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new).merge(super())
end

define_method :"#{name}_before_last_save" do
previous_changes[Mobility.normalize_locale_accessor(name)].first
end
@attribute_names.each do |name|
define_method :"saved_change_to_#{name}?" do
previous_changes.include?(Mobility.normalize_locale_accessor(name))
end

alias_method :"will_save_change_to_#{name}?", :"#{name}_changed?"
alias_method :"#{name}_change_to_be_saved", :"#{name}_change"
alias_method :"#{name}_in_database", :"#{name}_was"
define_method :"saved_change_to_#{name}" do
previous_changes[Mobility.normalize_locale_accessor(name)]
end
end
end

# Overrides +ActiveRecord::AttributeMethods::ClassMethods#has_attribute+ to treat fallthrough attribute methods
# just like "real" attribute methods.
#
# @note Patching +has_attribute?+ is necessary as of AR 5.1 due to this commit[https://github.com/rails/rails/commit/4fed08fa787a316fa51f14baca9eae11913f5050].
# (I have voiced my opposition to this change here[https://github.com/rails/rails/pull/27963#issuecomment-310092787]).
# @param [Attributes] attributes
def included(model_class)
names = @attribute_names
method_name_regex = /\A(#{names.join('|'.freeze)})_([a-z]{2}(_[a-z]{2})?)(=?|\??)\z/.freeze
has_attribute = Module.new do
define_method :has_attribute? do |attr_name|
super(attr_name) || !!method_name_regex.match(attr_name)
define_method :"#{name}_before_last_save" do
previous_changes[Mobility.normalize_locale_accessor(name)].first
end

alias_method :"will_save_change_to_#{name}?", :"#{name}_changed?"
alias_method :"#{name}_change_to_be_saved", :"#{name}_change"
alias_method :"#{name}_in_database", :"#{name}_was"
end
model_class.extend has_attribute
end
end
end
Expand Down

0 comments on commit 14a75a0

Please sign in to comment.