Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom fields in Rails that act as a template for future entries

I'm looking for some feedback on my current plan of implementing custom fields in rails. I'm new to rails and app development in general and would appreciate any comments from more experienced individuals.

Background

The app: Keep track of food and beverage tastings.

What I'm trying to model:

  • User creates a new sample type.
  • They call it: "Wine"
  • They decide for their company, they'd like to keep track of the following attributes: Origin, Grape Type, Company, Elevation,Temperature Kept, and more.
  • The only assumptions about a sample type that my database has made is that it has a Name. (eg. coffee, wine, etc.) the rest are all custom fields specified by the user.

Now that a sample type has been created.

  • The user begins to create samples of sample type wine.
  • They choose create sample, choose of type Wine.
  • The fields they must fill in are the ones they specified earlier.
  • In Origin they put: France, in Grape type: they put chardonnay, etc..

--

My plan of approach is as follows:

When a user creates the sample type, store the custom fields as an array or in some string format and keep it under a column called data.

SampleType
name
wine

data
[origin, grape_type, company, ...]

When a user wants to create a sample of type Wine: I look up the sample type wine, for each key in the data column, it creates form fields. When the user submits the data, I create a hash of all the custom fields names and their corresponding data. I serialize it and store it in a hash in a data column like such:

Sample
type
wine

data
{ origin: "France", grape_type: "Pinot Grigio, ... }

My plan at the moment is to use PostgreSQL's hstore to implement the hashing in the data column.

My questions are:

  1. Is this a valid solution for what I'm trying to do?
  2. Will I run into trouble when users change what custom fields they want?
  3. Any other concerns I should take into account?
  4. Is mongodb and other such db's a better choice for this type of model?

I've been using the following links as a reference: http://schneems.com/post/19298469372/you-got-nosql-in-my-postgres-using-hstore-in-rails http://blog.artlogic.com/2012/09/13/custom-fields-in-rails/

As well as many other stack overflow posts, however none seem to be using it in the way I mention above.

Any comments are appreciated.

like image 209
jtgi Avatar asked Nov 03 '22 06:11

jtgi


1 Answers

jtgi, having done something like this more times than I want to remember, my first response was, "run away!" In my experience, the whole user-defined field thing is an ugly, hacky, nightmare. Soon, someone will ask, "can I search on grape?" or "I want to be able to input multiple values for grape." And on and on, and you will hate yourself for ever stepping down this path. :-)

That said, I think your approach is pretty decent. To answer your questions directly:

  1. Yes, this is a valid approach.

  2. Yes, you will run into trouble when users change the custom fields they want. (see above)

  3. See some notes below.

  4. Might be. I went there even before I read your 4th question. With your field => value hash, you're kind of implementing a noSQL solution anyhow, but it'll be non-trivial to implement lookups, searches, etc.

Some thoughts:

  • I think I would marshal the data into a db column, rather than using a db function. That way, it's pure Ruby and not dependent on the db type. See http://www.ruby-doc.org/core-1.9.3/Marshal.html. I'm doing this to cache some data in an app right now, and it's pretty slick. You may need to marshal(l) the data anyhow, if you want to wind up storing Ruby objects more complex than strings.

  • You'll probably get there soon anyhow, so I would plan on storing some "metadata" about the attributes while you're at it. E.g., "grape" is a String, max length 20, "rating" is an integer between 0 and 100. That way you can make your form a little prettier and do some rudimentary validation.

  • When you come to hate this feature, you can remember me. :-)

like image 69
scrozier Avatar answered Nov 15 '22 04:11

scrozier