views:

224

answers:

5

Imagine a web application written in Ruby on Rails. Part of the state of that application is represented in a piece of data which doesn't fit the description of a model. This state descriptor needs to be persisted in the same database as the models. Where it differs from a model is that there needs to be only one instance of its class and it doesn't have relationships with other classes.

Has anyone come across anything like this?

+2  A: 

If it's data, and it's in the database, it's part of the model.

MattW.
+1  A: 

This isn't really a RoR problem; it's a general OO design problem.

If it were me, I'd probably find a way to conceptualize the data as a model and then just make it a singleton with a factory method and a private constructor.

Alternatively, you could think of this as a form of logging. In that case, you'd just have a Logger class (also a singleton) that reads/writes the database directly and is invoked at the beginning and end of each request.

AdamTheHutt
+1  A: 

In Rails, if data is in the database it's in a model. In this case the model may be called "Configuration", but it is still mapped to an ActiveRecord class in your Rails system.

If this data is truly static, you may not need the database at all. You could use (as an example) a variable in your application controller:

class ApplicationController < ActionController::Base
  helper :all 
  @data = "YOUR DATA HERE"   
end

There are a number of approaches that can be used to instantiate data for use in a Rails application.

Toby Hede
A: 

I'm not sure I understand why you say it can't fit in a Rails model.

If it's just a complex data structure, just save a bunch of Ruby code in a text field in the database :-)

If for example you have a complex nested hash you want to save, assign the following to your 'data' text field:

ComplexThing.data = complex_hash.inspect

When you want to read it back, simply

complex_hash = eval ComplexThing.data

Let me point out 2 more things about this solution:

  • If your data structure is not standard Ruby classes, a simple inspect may not do it. If you see #<MyClass:0x4066e3c> anywhere, something's not being serialized properly.
  • This is a naive implementation. You may want to check out real marshalling solutions if you risk having unicode data or if you really are saving a lot of custom-made classes.
webmat
+3  A: 

From your description I think the rails-settings plugin should do what you need.

From the Readme:

"Settings is a plugin that makes managing a table of global key, value pairs easy. Think of it like a global Hash stored in you database, that uses simple ActiveRecord like methods for manipulation. Keep track of any global setting that you dont want to hard code into your rails app. You can store any kind of object. Strings, numbers, arrays, or any object."

http://github.com/Squeegy/rails-settings/tree/master

Patrick Ritchie