Created
September 22, 2023 01:20
-
-
Save pangui/28b45c3601395ef52df649a7ef84388b to your computer and use it in GitHub Desktop.
This file contains hidden or 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