Storing Arbitrary Contact Information in Ruby on Rails
I am currently working on a Ruby on Rails app which will function in some ways like a site-specific social networking site. As part of this, each user on the site will have a profile where they can fill in their contact information (phone numbers, addresses, email addresses, employer, etc.).
A simple solution to modeling this would be to have a database column per piece of information I allow users to enter. However, this seems arbitrary and limited. Further, to support allowing users to enter as many phone numbers as they would like requires the addition of another database table and joins.
It seems to me that a better solution would be to serialize all the contact information entered by a user into a single field in their row. Since I will never be conditioning a SQL query on this information, such a solution wouldn't be any less efficient.
Ideally, I 开发者_高级运维would like to use a vCard as my serialization format. vCards are the standard solution to storing contact information across the web, and reusing tested solutions is a Good Thing. Alternative serialization formats would include simply marshaling a ruby hash, or YAML. Regardless of serialization format, supporting the reading and updating of this information in a rails-like way seems to be a major implementation challenge.
So, here's the question: Has anyone seen this approach used in a rails application? Are there any rails plugins or gems that make such a system easy to implement?
Ideally what I would like is an acts_as_vcard to add to my model object that would handle editing the vcard for me and saving it back to the database.
vCard is good for an API, but for the actual database I would use a 1-many design. Each person can have many phone numbers, addresses, email addresses, past employers. For current employer, you could do a 1-1 relationship. I think your aversion to joins is misplaced. With proper indexes, performance should be fine. Implementation will be much simpler than if you are constantly serializing and deserializing a denormalized string representation. You won't have to reinvent the wheel as you're contemplating.
1) if you do want to go the serialization route rails has built in support for storing a hash
from http://api.rubyonrails.org/classes/ActiveRecord/Base.html
class User < ActiveRecord::Base
serialize :preferences
end
user = User.create(:preferences => { "background" => "black", "display" => large })
User.find(user.id).preferences # => { "background" => "black", "display" => large }
if you use this technique I would put the serialized field on its own model/table object, otherwise it will be included in every User find call, which is not ideal, maybe
class User < ActiveRecord::Base
has_one :contact_info
end
class ContactInfo < ActiveRecord::Base
has_many :users
serialize :data
end
# ...
user.contact_info.data[:phone_numbers] # => ['999 999-9999', '000 000-0000']
2) or if you want to go the noSql route rails has support for mongodb, you would basically embed the contact info into the User model/document
- http://www.mongodb.org/
- http://railstips.org/blog/archives/2009/06/27/mongomapper-the-rad-mongo-wrapper/
- https://mongohq.com/home
3) or just go with the additional tables, it's not as bad as it seems, rails migrations can help a lot here with changing requirements
精彩评论