Skip to content

Instantly share code, notes, and snippets.

@davingee
Created April 1, 2019 21:52
Show Gist options
  • Save davingee/22ed588f710fcb0f89f5b78d4b55a433 to your computer and use it in GitHub Desktop.
Save davingee/22ed588f710fcb0f89f5b78d4b55a433 to your computer and use it in GitHub Desktop.
module ActiveRecord
module Type
class Json < ActiveModel::Type::Value
include ActiveModel::Type::Helpers::Mutable
def deserialize(value)
value = '{}' if value.is_a?(::NilClass)
return value unless value.is_a?(::String)
ActiveSupport::JSON.decode(value) rescue nil
end
end
end
end
module ActiveRecordConcern
def json_attr_accessible(args = {})
# binding.pry
column = args[:json_column].to_s
key_names = args[:key_names]
# {
# :json_column => :data,
# :key_names => [
# {
# :name => :card_type
# },
# {
# :name => :high,
# :parent => :apr
# },
# {
# :name => :low,
# :parent => :apr,
# :prefix_column_name => true
# :fall_back => :product
# }
# ]
# }
key_names.each do |hsh|
method_name = hsh[:child] ? "#{hsh[:name]}_#{hsh[:child]}" : hsh[:name]
method_name = "#{hsh[:json_column]}_#{method_name}" if hsh[:prefix_column_name] == true
define_method("#{method_name}=") do |val|
# self.send("#{column}=", {}) if self.send(column).nil?
# send("#{serialized_attribute_name}_will_change!")
if hsh[:child]
(send(column)[hsh[:name].to_s] ||= {})[hsh[:child].to_s] = val
else
send(column)[hsh[:name].to_s] = val
end
end
# if hsh[:fallback]
define_method("#{method_name}_no_fallback") do
if hsh[:child]
read_attribute(column)[hsh[:name].to_s].try(:[], hsh[:child].to_s)
else
read_attribute(column)[hsh[:name].to_s]
end
end
# end
define_method("#{method_name}") do
if hsh[:fallback]
val = send("#{method_name}_no_fallback")
return val if val.present?
fallback_item = send(hsh[:fallback])
fallback_item.try(:send, method_name)
else
send("#{method_name}_no_fallback")
end
end
define_method("#{method_name}?") do
send(method_name).present?
end
# attr_accessible "#{serialized_attribute_name}_#{name}"
end
end
extend ActiveRecordConcern
belongs_to :product, required: false
delegate :payout,
to: :product
attr_accessible_with_fallback(:product,
:description
)
json_attr_accessible( {
json_column: :data,
key_names: [
{ name: :card_type, fallback: :product },
{ name: :apr, child: :high },
{ name: :apr, child: :low, prefix_column_name: true },
],
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment