Strategy for storing/accessing custom attributes?

I’m working on a contact management app and 3 of the requirements are:

  • the user should be able to add additional custom Contact fields
    (e.g. an extra phone number that isnt provided in the std set of
    fields)
  • the user should be able to name fields with whatever label they want
    (e.g. one user might label with “Vacation Phone”, another as “Home
    Office Phone”
  • the custom data will be typed and grouped so that we know that it’s
    text data vs a phone number (for example) and so that we can get the
    list of all custom phone numbers or addresses

I’m more concerned with the first req right now regarding storage and
the best way to then access and use this data, but am glad to hear
thoughts on the others as well.

My thought is to have a column in the DB called “custom” that’s a text
field and then either go with a YAML style or XML for storing the
field label and data.

But, what’s the best way to encapsulate and do things in the model
code to make these attributes accessible from the rest of the app in a
way thatis transparent to those other parts of the app?

Perhaps the serialize method could be helpful:

http://apidock.com/rails/ActiveRecord/Base/serialize/class

Cheers,
Nicholas

thx nicholas

I’d thought of using serialize, but decided to just do it as yaml

so, for the moment, I’m good on my first req

the third req of being able to group/type the custome field data will
either be handled by structuring the yaml or I may split things into
seperate colums for te diff types of data… this may help with
searches a bit

the second req is what’s befuddling me now… with fixed field names,
I can create attr_accessors for each of them and do explicit setter/
getters for each attribute… but having a dynamic list of attributes,
both in count and attr name, I’m not sure how to set that up…

can anybody help with that?

vitaly, thx for your ideas

I hadnt really considered going the way you suggest, prob due to some
sense that that would make the object model way more complexe for a
Contact (has_many :phone_numbers, has_many :addresses,
has_many :emails, etc)… I kinda like that, though, now that you
suggest it.

2 follow on questions for you (and others):

  1. might this be less efficient performance-wise if everything is
    scattered across tables?

  2. since the req is to let them create any number of arbitrary fields,
    it seems like there will be those that wont fit as nicely into the
    has_many constructs I outline above… I think I’d have to either
    still do this cisutom field column or maybe have something like
    has_many :custom_text_fields to put them in… thoughts on that part?

Thx again.

From the question I guess that you have added multiple “standard”
address and phone fields to the contact record, i.e. you have
something like home_address, work_address, home_phone and work_phone
columns in your table, which I think is a bad idea to begin with.
This makes it very ugly to do stuff like ‘who has the phone XXX’ or
who lives in New York etc.
The right way to do it is to have a separate addresses and phones
tables and to have a separate record there for any phone/address you
have for the contact. Then your ‘standard’ fields will be just
suggestions in the interface for the ‘description’ field of a relevant
record. i.e. in the database there will be no difference between ‘home
address’ and ‘my super secret hideaway address’ other then the
‘description’ text.
As an additional benefit this approach will make it practical to break
down the records into subfields, e.g. address, city, zip code,
country. etc. (and it would be absolutely insane to do it while
stuffing all into a single contact record, or you would end up with
literally hundreds of fields)

to make the access ‘transparent’ to the rest of the app you need to
consider 2 things:

since there is no difference between the records you can access them
all the same. i.e. you have contact.addressess, contact.phone_numbers
etc. you can have custom methods on the associations to do stuff like
contact.addressess[“home address”] if you really need it :slight_smile: