0

I need an opinion about how to structure my models for a rails 4 app I'm doodling on. The architecture shouldn't be too hard but I've been going in circles for hours so I'll throw it out to the community.

I have a model called "checkin" that has_many "fields". Each field can have many values that can be one of several data types that may increase in number over time but for starters will be just float and string. Once a field is added to a checkin its data type cannot change.

Think of a checkin for losing weight where some people would want to log just weight. Others might want to log weight, %bodyfat. Others might want extra fields for other metrics or a text field for what mood you're in.

So what I've got so far is:

class Checkin < ActiveRecord::Base
  has_many :fields

class Field < ActiveRecord::Base
  belongs_to :checkin

And then I was going to do

class DataFloat < ActiveRecord::Base
  belongs_to :field

class DataString < ActiveRecord::Base
  belongs_to :string

etc.

The schema is simple with just references for now. DataFloat has a float and DataString has a string (as you'd expect)

Then I'll use something like ActiveRecord::Base.descendants a (as per THIS) to create a select box so that you can choose what a field is when you add it to the checkin.

My question for all those MVC experts out there is whether or not this is the best way to do this. Would I be better off having a central object "Data" that is extended by DataFloat and DataString? Is there a third, better way I haven't thought of?

Community
  • 1
  • 1
Raychaser
  • 340
  • 2
  • 12

1 Answers1

0

Anyone...... bueller?

I managed to solve it but it took a long time to find the correct term for what I was trying to do. It's basically polymorphic associations in reverse.

There's a fantastic tutorial by Rune Madsen here: https://gist.github.com/runemadsen/1242485

basically I do it this way:

class Field < ActiveRecord::Base
  has_many :field_datas
  has_many :data_ints, :through => :field_datas, :source => :data_object, :source_type => 'DataInt'
  has_many :data_floats, :through => :field_datas, :source => :data_object, :source_type => 'DataFloat'
   .... etc.....

Then I do:

class FieldData < ActiveRecord::Base
  belongs_to :field
  belongs_to :data_object, :polymorphic => true
end

And then finally the actual data which is a table with an id and one column:

class DataInt < ActiveRecord::Base
  has_one :field_data, :as =>:data_object
  has_one :field, :through => :datas

And then there would be a DataType class for each data type.

I think I will probably need to write special handlers to make sure everything gets destroyed and created properly but overall I'm pretty pleased with it.

I would love to know if anyone has an opinion about doing it this way.

Raychaser
  • 340
  • 2
  • 12