ActiveRecord, mapping a column value to a symbol

Hi

Is it possible to map a column value to a symbol?

For example, lets say I have an integer in a table that will hold -1, 0 or 1

I want these to map to :negative, :neutral, :positive

Or is there a better way to accomplish this. I want something similar to an enum in C, so that from code i can can talk about things in terms of abstract values, but that are stored in one column in the DB.

The other way I could do this would be to have another table mapping the values, but this seems unnecessarily expensive.

Thanks Ryan

Ryan wrote:

Hi

Is it possible to map a column value to a symbol?

For example, lets say I have an integer in a table that will hold -1, 0 or 1

I want these to map to :negative, :neutral, :positive

Or is there a better way to accomplish this. I want something similar to an enum in C, so that from code i can can talk about things in terms of abstract values, but that are stored in one column in the DB.

The other way I could do this would be to have another table mapping the values, but this seems unnecessarily expensive.

Thanks Ryan

I might create a method like the following...

def symbolized_value    case value       when 1 : :positive       when 0 : :neutral       when -1 : :negative    end end

Ryan wrote:

For example, lets say I have an integer in a table that will hold -1, 0 or 1

I want these to map to :negative, :neutral, :positive

If you will just want to compare if an object has one of these values, then instead of have lots of "object.value == :negative" and so forth, you could define some predicates on your class:

def negative?   value == -1 end

etc. Then instead of using the symbols, you hide the values in these predicates.

You can define similar setters:

def negative   value = -1 end

Depending on how you intend using the values, there's a number of things you can do to hide the implementation from users of the model.

Ryan wrote:

Hi

Is it possible to map a column value to a symbol?

For example, lets say I have an integer in a table that will hold -1, 0 or 1

I want these to map to :negative, :neutral, :positive

class SomeModel < ActiveRecord::Base

  VALUE_MAP = {:negative => -1, :neutral => 0, :positive => 1}

  def value=(sym)     write_attribute :value, VALUE_MAP[sym]   end

  def value    VALUE_MAP.invert[read_attribute(:value)]   end

end

hth

ilan

Thanks for the help. Just tried out Ilan's solution and works great.

Instead of:   VALUE_MAP.invert[read_attribute(:value)] It's a bit more efficient/elegant to use   VALUE_MAP.key[read_attribute(:value)]

If you have a larger map and/or efficiency is important you could also use an array: VALUE_MAP = [:negative,:neutral,:positive] def value=(sym);self[:value]=VALUE_MAP.index(sym)-1;end def value;VALUE_MAP[read_attribute(:value)+1];end -j

I get a NoMethodError when using key. I'm using Ruby 1.8.6

Hello everyone,

Can anyone recommend a blogging engine that would suit my needs? My website would require multiple blogs, each "owned" by a different user, with each being separately customizable. Right now I'm making use of separate WordPress installations for each user, but I would rather find a solution that could be integrated with the rest of the application instead of switching back and forth between Rails and PHP (for WordPress).

I've looked at several blogging engines, but most of them seem geared towards just one blog, or one blog with multiple authors and not multiple blogs with one author each. Is there anything out there which I could use and modify, or am I pretty much stuck writing my own engine to accomplish it? As far as the blog itself goes, we don't need much more than the ability for authors to write posts, others to post comments, and the standard search/archive stuff.

Any help would be appreciated.

Regards,

Wayne M. Co-Founder, LibertyTruth.org

No virus found in this outgoing message. Checked by AVG. Version: 7.5.518 / Virus Database: 269.21.6/1318 - Release Date: 3/7/2008 2:01 PM

I believe that's a typo. It probably should be:

VALUE_MAP.keys[read_attribute(:value) + 1]

Fjan wrote:

Instead of:   VALUE_MAP.invert[read_attribute(:value)] It's a bit more efficient/elegant to use   VALUE_MAP.key[read_attribute(:value)]

If you have a larger map and/or efficiency is important you could also use an array: VALUE_MAP = [:negative,:neutral,:positive] def value=(sym);self[:value]=VALUE_MAP.index(sym)-1;end def value;VALUE_MAP[read_attribute(:value)+1];end -j

Fjan,

I like that solution much better than mine, I kick myself for not having not thought of the array solution instead of the map! You may have won this round but the war isn't over! :slight_smile:

ilan

@Ryan/Mike

I get a NoMethodError when using key. I'm using Ruby 1.8.6

Sorry, you are right, it's a new method in Ruby 1.9, I didn't realize that. A hash invert is kind of an expensive thing to do on every call so then I'd rather do the invert once and store it in a constant, or use the array version.

@ilan The real Ruby-ists don't worry about performance they tell me :slight_smile: