cmswalker / cauldron

0 stars 0 forks source link

flatten stored data #18

Open nathanallen opened 9 years ago

nathanallen commented 9 years ago

Seems to me you are trying to store your chart data exactly as you would need it to render your views. I'd encourage you to store it in as simple a format as possible, and then format it for your view.

For example, it's common to store timestamps in an un-human-readable format, but then to "stringify" them into some local format, e.g. "21 July 2015", or "July 21st". This is a good way to separate concerns between the model and the view.

Here's a quick pass at it --> moving from a simple array of strings to a nested object.

// ["Vodka", "Creamer"]

{
  "name": null,
  "children": [
    {
      "name": "Vodka",
      "children": [
        {
          "name": "Creamer",
          "children": []
        }
      ]
    }
  ]
}

Code:

var data = ["Vodka", "Creamer"]

var template = {
  name: null,
  children: [],
}

function clone(o){
  // quick way to clone objects
  var serialized = JSON.stringify(o);
  return JSON.parse(serialized);
}

function to_nested_object(data, template){
  var output = clone(template),
      children = output.children,
      o;

  data.forEach(function(v,i){
    o = clone(template);
    o.name = v;
    children.push( o );
    children = o.children;
  })

  return output;
}

to_nested_object(data, template)

The point being, if I store it as "flat" as possible, it's easy for me to retrieve/format it properly for the view. If I store the way the view wants it, it's extremely tricky for me to manipulate.

nathanallen commented 9 years ago

One advantage of this approach is it would allow you to have a Drinks (or Recipes) model and you'd be able to edit them (currently not easy to do). An individual chart instance would then just be a collection of drinks (has_many). I might even recommend skipping the ingredients class in that case, to simplify things further.

The tricky part is going from multiple individual drinks to the nested data-structure your chart needs. A trie structure makes sense, but the real problem is that one user might type "vodka" and another "Vodka" and yet another "Sky Vodka", so you'd still need a way to standardize ingredients / types of ingredients to nest properly. For starters I'd just offer auto-complete suggestions to the user based on the names of ingredients they've already submitted for that particular chart. Eventually you could create canonical ingredients and categories, but don't bother yet.

cmswalker commented 9 years ago

Yeah this makes much more sense and makes it more flexible for later. I'll try to get these resolved by the weekend. I have angular doing tier-level autocomplete but it would make more sense to just open it up to everything in the chart to avoid confusion. Thanks again.