I am sure that all of the programmers out there will say “Well, Duh!” but I wanted to put this into writing for my own purposes. Basically so I do not forget it. If you happen to get some good ideas from it, well then score.
So, I have several models which all need to have attributes. Not all of them need the same attributes, however we want a method of quickly searching and creating new types of attributes for models.
Suppose we have the following models:
All of these might have a attribute of color, but only the computers will have an IP Address. However, we want to be able to search all computers based on the IP address. Just to make it more difficult, Laptops, Servers and Desktops are all computers.
My solution at this time is to create another model, which I have called Attributes. This has the following layout:
1 2 3 4 5 6 7 8 9 10
class Attribute < ActiveRecord::Base belongs_to :owner, :polymorphic => :true # Attribute has the following fields: # owner_type as string # owner_id as integer # type as string # value as string end
Each of my models which will use these will include the has_many directive:
has_many :attribute, :as => :owner
When a new instance of a model is created, I run an after_create function (which I cleverly call Templater) which figures out which type (or species) of model is being created, and pre-populates a default set of attributes.
For example, a Laptop might be created with the attributes: CPU, RAM, IP Address, and OS. In fact, all computers could be created with that same default set of attributes. Then, when we decide to build a query that gives us all computers with less them 1024 megs of RAM, we can simply search the attributes table for all records where type is RAM and value is less then 1024, and return their owner ID’s.