What is the proper role of seed data?

Hi,

In my Rails app, I have some parameters whose values change only
infrequently. These parameters are used in computations. Where is the
place for data like this – data that is particular to the
application?

On the one hand, I might think a flat file (yaml) is appropriate, but
maybe I shouldn’t sacrifice the benefit of modeling my parameters as
seed data in the seed.rb file.

Thanks for any comment,

Grar

Grary wrote:

Hi,

In my Rails app, I have some parameters whose values change only
infrequently. These parameters are used in computations. Where is the
place for data like this – data that is particular to the
application?

On the one hand, I might think a flat file (yaml) is appropriate, but
maybe I shouldn’t sacrifice the benefit of modeling my parameters as
seed data in the seed.rb file.

I use seed data in basically two ways:

  1. As a starting point for the production database.

This provides a mean to pre-plan the starting point for the production
database. This might include things like setting up an admin user, user
roles, collections for pull-down lists, etc.

  1. For populating development data.

This provides a convenient way to reset my development database to match
the data where my production environment will start.

I would not, however, use seed data in the way you’re describing.
Instead I would use either a static configuration file or use the
database. For data that I would never want the users to be able to
change I would use a configuration file (a sort of property list). For
data that could possibly be altered by the users, or administrators, I
would use the database to store the values.

Think of seed data as a means of “bootstrapping” your database. You
would likely only ever run the seed data script once on the production
database, but possibly many times on the development database.

Robert,

Thanks for your reply, you really nail it:

Instead I would use either a static configuration file or use the
database. For data that I would never want the users to be able to
change I would use a configuration file (a sort of property list). For
data that could possibly be altered by the users, or administrators, I
would use the database to store the values.

Please appreciate that, for a novice, the integration of database with
model is so tight, it’s hard to think about a Rails web app using a
database without going through a model!

So, I think that my data should be accessible by administrators, but
what is the Rails mechanism for that access? Am I going to be issuing
raw SQL commands?

Thanks for any additional comment,

Grary

Grary wrote:

So, I think that my data should be accessible by administrators, but
what is the Rails mechanism for that access? Am I going to be issuing
raw SQL commands?

Essentially, anything that can be stored in a database table can be
modeled. From what I understand from your original post, you have a set
of values that could possibly be changed, but not often.

Let’s make sure I understand your requirements:

  • You need to store a list of values that are to be used in in
    calculations.
  • There is a fixed number of different parameters. Let’s call them (x, y
    & z).
  • The parameters x, y & z will be initialized to known values.
  • The values of x, y & z are normally fixed, but can be altered by users
    (administrators) at runtime.

Here are some options:

  1. Use a configuration file to store key/value pairs.
  2. Use a database with a single row containing the values in the columns
    of the table.

±—±-----±-----±------+
| id | x | y | z |
±—±-----±-----±------+
| 1 | 10.0 | 12.5 | 0.124 |
±—±-----±-----±------+

  1. Use a database table with multiple rows to simulate a key/value
    store.

±—±------±------+
| id | key | value |
±—±------±------+
| 1 | x | 10.0 |
| 2 | y | 12.5 |
| 3 | z | 0.124 |
±—±------±------+

The advantage here is that the number of parameters the is not fixed. No
need to add a new column to add a new key/value.

  1. Use an actual key/value persistent store
    (Google Code Archive - Long-term storage for Google Code Project Hosting.).

This is very probably overkill for your situation.

In all of these cases you could use seeds.rb to initialize your values.
From what I can glean I’d most likely go with option 1. Use a
configuration file (YAML). If the administrator needs to change the
configuration then just update the file with the new parameter. You will
also like want to cache these values in some form of memory cache so you
don’t have to read the values from disk/database on every request. Take
a look at memcached.

Robert,

Another high quality response, thank you.

Let me respond briefly, selectively to your reply…

  • The parameters x, y & z will be initialized to known values.
  • The values of x, y & z are normally fixed, but can be altered by users
    (administrators) at runtime.

Yes, very infrequently, e.g., once a year, parameters used as
constants in application computations will change and will need to be
changed by an administrator. So, these parameters are global.

  1. Use a configuration file to store key/value pairs <…> Use a
    configuration file (YAML). If the administrator needs to change the
    configuration then just update the file with the new parameter. You will
    also like want to cache these values in some form of memory cache so you
    don’t have to read the values from disk/database on every request. Take
    a look at memcached.

I agree with you that this is likely the best approach for my
situation.

Borrowing from http://railsforum.com/viewtopic.php?id=15295, I might
read/write to my file via the following mechanism:

a_config = YAML.load_file “#{RAILS_ROOT}/config/application.yml”
a_config[“user”][“pwd_days”] = params[:days]
File.open(“#{RAILS_ROOT}/config/application.yml”, ‘w’) { |f|
YAML.dump(a_config, f) }

Look good?

Two final questions for you:

  1. Regarding the use of memcached for efficiency, it is a efficiency
    option available for flat file and database persisted data, alike,
    right? So, I might look forward to its use in varied manner of
    performance tuning?

  2. In all of these cases you could use seeds.rb to initialize your
    values.

So, seeds is kind of like providing a user with a place to start,
e.g., standardized settings, that they may then wish to change? It is
not really for classic configuration, i.e., it does not involve global
settings.

Grar