2

I have a column on my model User called properties which is jsonb. As i have the requirement for user generated dynamic fields.

How would you access the attributes as if they were normal mapped columns

E.g User model has a column called first_name but a property in the properties called eye_color

user = User.find(1)
user.first_name # => "john"
# to access the eye color you would do
user.properties['eye_color'] # => "green"

What I would like to do is to be able to call the map json attribute so i can set and get it via like bellow

user.eye_color = 'green'

This needs to be dynamically done as the field attributes can change. However, at the user instance I can see work out what all the attributes will be.

Jake McAllister
  • 1,037
  • 3
  • 12
  • 29
  • I made something for this that _might_ solve your problem. https://github.com/joshmn/setsy – Josh Brody Apr 03 '19 at 19:04
  • [Another possible solution](https://stackoverflow.com/a/18815753/4988918) in addition to @joshbrody...I'd ask why you need this functionality if the keys are dynamic though...you won't know ahead of time (assumingly) what the keys are...so why not just use `user.properties['eye_color']`? – Mark Merritt Apr 03 '19 at 20:49

1 Answers1

1

Maybe try overriding method_missing on your User model

def method_missing(method, *args, &block)
  clean_method = method.to_s.chomp('=')

  if properties.key?(clean_method)
    if method.to_s.ends_with?('=')
      return properties[clean_method] = args.first
    else
      return properties[clean_method]
    end
  end

  super
end

This should allow you to get and set directly

# set value
user.eye_color = 'green'

# get value
user.eye_color # => returns 'green'
chanko
  • 269
  • 1
  • 5
  • How would you suggest you map back the datatype? i.e. if what you pass is a datetime when you call the method name it parses into a datetime – Jake McAllister Apr 03 '19 at 19:13
  • I'm not sure. In your jsonb field, numbers will be saved as numbers and anything else will be saved as a string. How are you originally getting the fields? Are users selecting the datatype of the field at the time of input? – chanko Apr 04 '19 at 19:08
  • Yes the user would chose the datatype. eg time, dattime, text, decimal, etc – Jake McAllister Apr 05 '19 at 18:33
  • Sorry @JakeMcAllister I totally lost track of this. Were you able to figure out a solution to your problem? – chanko Apr 12 '19 at 21:53