Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Constants Hash?

I have a need for a model(?) on my app which basically contains a status of another entity. In the entity I want to store the id of the status, but in my app, the view is talking in terms of a nice word description. For instance, 1=New, 2=Used etc etc.

How can I go about implementing this in the best way that means I can easily set and retrieve this status column without repeating myself?

Ultimately I would like something like

Foo.status = 'New'  (actually sets value to 1)

and

Foo.status  (returns 'New', but stores 1)

Am I even thinking about this in the right way?

like image 384
Neil Middleton Avatar asked May 03 '09 21:05

Neil Middleton


People also ask

How do you change a constant value in Ruby?

In Ruby, Constant is another type of variable, the only difference is that we cannot change the value of the constant throughout the program. In case if we try to change the value of the variable it will raise a warning error.

How do you write a hash in Ruby?

In Ruby you can create a Hash by assigning a key to a value with => , separate these key/value pairs with commas, and enclose the whole thing with curly braces.

What do you mean by constants in Ruby?

A constant in Ruby is like a variable, except that its value is supposed to remain constant for the duration of a program. The Ruby interpreter does not actually enforce the constancy of constants, but it does issue a warning if a program changes the value of a constant.


2 Answers

You can code a custom writer method:

STATUS_VALUES = { 1 => 'new', 2 => 'modified', 3 => 'deleted' }

class Foo
  attr_reader :status_id

  def status
    STATUS_VALUES[@status_id]
  end

  def status=(new_value)
    @status_id = STATUS_VALUES.invert[new_value]
    new_value
  end
end

For example, the following program:

foo_1 = Foo.new

foo_1.status = 'new'
puts "status: #{foo_1.status}"
puts "status_id: #{foo_1.status_id}"

foo_1.status = 'deleted'
puts "status: #{foo_1.status}"
puts "status_id: #{foo_1.status_id}"

outputs:

status: new
status_id: 1
status: deleted
status_id: 3
like image 170
Rômulo Ceccon Avatar answered Nov 15 '22 16:11

Rômulo Ceccon


I'd just go ahead and use symbols, something like

Foo.status = :new

They're basically immutable strings, meaning that no matter how many times you use the same symbol in your code, it's still one object in memory:

>> :new.object_id
=> 33538
>> :new.object_id
=> 33538
>> "new".object_id
=> 9035250
>> "new".object_id
=> 9029510 # <- Different object_id
like image 40
esad Avatar answered Nov 15 '22 15:11

esad