Skip to content

Instantly share code, notes, and snippets.

@onemanstartup
Created January 11, 2015 06:42
Show Gist options
  • Save onemanstartup/2df9aa2d7d037256cd23 to your computer and use it in GitHub Desktop.
Save onemanstartup/2df9aa2d7d037256cd23 to your computer and use it in GitHub Desktop.
# You don't actually need this.
# I wrote this, but rails support this
# Use store_accessor :data, :admin
module JsonAccessor
extend ActiveSupport::Concern
module ClassMethods
def json_accessor(json_attribute, *fields)
send(:store, json_attribute, accessors: fields)
field_methods = Module.new
fields.each do |any_key|
key = any_key.to_s.freeze
field_methods.send(:define_method, "#{key}_changed?") do
send("#{key}_change").present?
end
field_methods.send(:define_method, "#{key}_will_change!") do
send("#{json_attribute}_will_change!")
end
field_methods.send(:define_method, "#{key}_was") do
(send(:attribute_was, json_attribute) || {})[key]
end
field_methods.send(:define_method, "#{key}_change") do
json_changes = send("#{json_attribute}_change")
return if json_changes.nil?
attribute_changes = json_changes.map { |change| change.try(:[], key.to_s) }
attribute_changes.compact.present? ? attribute_changes : nil
end
field_methods.send(:define_method, "restore_#{key}!") do
old_json = send("#{json_attribute}_change").try(:first) || {}
send("#{key}=", old_json[key.to_s])
end
include field_methods
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment