dsp_099
dsp_099

Reputation: 6121

Is it acceptable to have a single instance of a model to keep "global", alterable information?

I ran into a problem which required me to have access to a bunch of variables which need to be changed every so often, so I made a Misc model and there is only ever one instance of it. This was my solution for having editable global variables.

It holds all types of stuff that didn't seem like they deserve their own models. Is this acceptable or does this violate some Rails-buliding principle I'm not aware of? It works, but I have doubts.

Is there a better alternative to this strategy (think fetching/editing (as an example) Misc.first.todays_specials).

If this is passable, then is there a way to prevent a creation of more than one item of a model in the database? The problem with the above approach as you can see is that if there are all of a sudden TWO entries for Misc, things will get wonky as it requests the .first under the assumption that there's ever only going to be one.

Upvotes: 0

Views: 109

Answers (3)

Uri Agassi
Uri Agassi

Reputation: 37409

Using a singleton to hold global state is a very bad idea, especially in a web-server:

  1. If you are using a multi-threaded environment - you will run into thread-safety issues.
  2. More relevantly - if you run multi-process, or multi-server (as you would have to, if your web application ever succeeds...) - the state will be inconsistent, as changes in one process/machine will not be propagated to the other processes/machines.
  3. A restart of your application will destroy the state of the application, since it is held only in memory.

You could use an SQL solution, as suggested by @Tala, but if you want something more light-weight and 'freestyle', you might want to look at some key-value stores like memcached or redis, where you could save your state in a central location, and fetch it when needed.

Upvotes: 0

Alive Developer
Alive Developer

Reputation: 1022

you could use a singleton pattern.

a singleton class is a class that can only have one instance.

so you could do something like this:

initializers/config.rb

require 'singleton'

class MyConfig
  include Singleton

  attr_accessor :config1


  def initialize
    self.config1 = ["hello", "world"]
  end
end

and use it in this way:

MyConfig.instance.config1

You can also consider global variables. Global variables are those which start with the $ sign, and are accessible in the whola application by all instances of your ws.

Upvotes: 1

Tala
Tala

Reputation: 8928

You can create a table for Settings storing key-value configs. It will be scalable and not depend on predefined keys. Also you won't have a table with one row this way.

If you need lots of read/writes you might also want to cache rails SQL Caching

Upvotes: 1

Related Questions