-
-
Save alekpopovic/b7a4dab6466bce3a1037e66fd242ab0b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'json' | |
class Person | |
@age = nil | |
attr_accessor :json_field, :age | |
def initialize *args | |
# useful for Rails ApplicationRecord models | |
args[0].each{|key, value| self.send("#{key}=".to_sym, value)} | |
# uncomment next line for inherited classes | |
# super *args | |
end | |
# catch missing methods | |
def method_missing name, *args | |
# @davidbella's inspiration: https://gist.github.com/davidbella/6918455 | |
# define json accessor to read/write data in json_field | |
attribute_name = name.to_s.gsub(/=$/, '') | |
self.json_field ||= {} | |
# define charles.{attribute_name} = value | |
self.class.send(:define_method, "#{attribute_name}=".to_sym) do |value| | |
self.json_field.send(:[]=, attribute_name, value) | |
end | |
# define charles.{attribute_name} | |
self.class.send(:define_method, attribute_name.to_sym) do | |
value = self.json_field.send(:[], attribute_name) | |
end | |
# call defined method | |
send(name, *args) | |
end | |
# Just for object inspection | |
def to_h | |
Hash[instance_variables.map{|var| [var, instance_variable_get(var)] }] | |
end | |
end | |
# Initialize instance and assign dynamic and static attributes | |
charles = Person.new({first_name: 'Charles', age: 35}) | |
# | |
# Verify dynamic attribute | |
puts charles.first_name.inspect | |
# -> "Charles" | |
# | |
# Assign more dynamic variables and check json field | |
charles.country, charles.city = 'UK', 'London' | |
puts JSON.pretty_generate(charles.json_field) | |
# -> { | |
# "first_name": "Charles", | |
# "country": "UK", | |
# "city": "London" | |
# } | |
# | |
# Inspect instance attributes | |
puts JSON.pretty_generate(charles.to_h) | |
# -> { | |
# "@json_field": { | |
# "first_name": "Charles", | |
# "country": "UK", | |
# "city": "London" | |
# }, | |
# "@age": 35 | |
# } | |
# | |
# For ApplicationRecord, remember to notfify changes before save | |
# charles.json_field_will_change! | |
# charles.save |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment