views:

147

answers:

3

Hello. There are a lot of ways to store site preferences in database. But what if I need to manage datatypes. So some preferences will be boolean, others strings, others integers.

How can I organize such store?

A: 

Rails Migrations are used to create and update the database.

http://guides.rubyonrails.org/migrations.html

Swards
A: 

I am quite lazy with preferences and store the data as serialized JSON or YAML Hashes. Works really well, and generally preserves the data types as well.

Toby Hede
What about using a schemaless database instead?It'll perform much better, and is easier to query with JSON hashes.
CodeJoust
You could, but then you need to either ditch your RDBMS for everything, or run the two together increasing your costs. Performance of pulling a string from the database to deserialize is pretty good, especially when using JSON and the JSON gem. You will still have the deserialization overhead using a db like MongoDB.
Toby Hede
A: 

I used a single table with a single row, and each column representing one preference. This makes it possible to have different datatypes.

To be able to retrieve a preference, I overrode method_missing to be able to retrieve the preference value directly from the class name without requiring an instance, something like this:

class Setting < ActiveRecord::Base
  @@instance = self.first

  def self.instance
    @@instance
  end

  def self.method_missing(method, *args)
    option = method.to_s
    if option.include? '='
        var_name = option.gsub('=', '')
        value = args.first
        @@instance[var_name] = value
      else
        @@instance[option]
    end
  end
end

Thus, to retrive a setting, you would use:

a_setting = Setting.column_name
JRL
It is ok, but what if I want Settings to have field called, 'data_type'? So settings could be for example integers, floats, booleans.
Igor Alexandrov
@Igor: that would be useless. By using a column-based storage, you can have the database define the datatype, and you do not need to have a separate column for it. You are thinking about having one row per setting, and one column for the datatype. My example is a single row, and each column can be whatever datatype you want.
JRL
E.g., an example Settings migration would be: `create_table "settings" do |t|` `t.boolean "master"` `t.integer "default_id"` `t.string "name"` `end`
JRL
@JRL yes, maybe you are right :)
Igor Alexandrov