Design question - where to store constants?


#1

Let’s say I create a “ticket system” that has a support ticket with a
status attached to it. (Say, OPEN or CLOSED for now, but more later)

The status -could- be another table in the database listing status
types, but I think that’s unnecessarily complex and overly flexible for
this. (opinions on this point would be interesting)

Another alternative would be to define the statuses as a constant within
the application:

ticket_status = [“Open”, “Closed”]

Where is this constant declaration best suited? At the App level in the
CONFIG[]? Or in the model for the ticket? The controller for the
ticket? It seems to be a model thing.

Jake


#2

Jake J. wrote:

Let’s say I create a “ticket system” that has a support ticket with a
status attached to it. (Say, OPEN or CLOSED for now, but more later)

The status -could- be another table in the database listing status
types, but I think that’s unnecessarily complex and overly flexible for
this. (opinions on this point would be interesting)

Another alternative would be to define the statuses as a constant within
the application:

ticket_status = [“Open”, “Closed”]

Where is this constant declaration best suited? At the App level in the
CONFIG[]? Or in the model for the ticket? The controller for the
ticket? It seems to be a model thing.

Jake

You could define it in environment.rb:
TICKET_STATUS = [“Open”, “Closed”]

Or in the model, it doesnt really matter.


#3

Hi –

On Sun, 12 Feb 2006, Jake J. wrote:

ticket_status = [“Open”, “Closed”]
That’s not a constant – do you mean TICKET_STATUSES or something?
(Actually if you have a Ticket class you would probably want a
constant just called STATUSES.)

Where is this constant declaration best suited? At the App level in the
CONFIG[]? Or in the model for the ticket? The controller for the
ticket? It seems to be a model thing.

I think it’s a model thing. Basically, you’re trying not to have to
type the list of statuses over again if it’s used in multiple methods.
So it’s just an abstraction one level up:

class Ticket < ActiveRecord::Base

 STATUSES = %w{ Open Closed }  # or whatever :-)

 def check_status
   STATUSES.include?(status)
 end

 def something_else
   # do something else with STATUSES
 end

end

No need to stash it further away than this. It makes sense, too, that
the statuses list would be a class-level resource of Ticket.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#4

First of all for this case it’d probably be best just to make it a
boolean. It’ll lead to natural code, like

if ticket.open?

If you really want to go for string statuses though, David’s code
looks pretty good. I’d do something like,

class Ticket < ActiveRecord::Base
Open= ‘open’
Closed = ‘closed’
Statuses = [Open, Closed]

def status_is?(s)
status == s
end
end

This would lead to the reasonably natural code:
if ticket.status_is?(Ticket::Open)

You can then also create an open? method, which just checks the status
with a default val (open classes make it more fun to write mailing
list posts :slight_smile:

class Ticket < ActiveRecord::Base
def open?
status_is?(Open)
end
end

The very last thing is that you will want to write a validation:

class Ticket < ActiveRecord::Base
def validate
unless status and Statuses.include?(status)
errors.add(:status, ‘must be one of the following: ’ +
Statuses.join(’, ')
end
end
end

Anyway, imo this is all a pretty ugly to solution when it can be
solved by simply making this field a boolean.

Pat


#5

On Sun, 2006-02-12 at 18:50 -0700, Pat M. wrote:

First of all for this case it’d probably be best just to make it a
boolean. It’ll lead to natural code, like

if ticket.open?


OK - I asked the other day and didn’t get a bite so since you mentioned
it…

I am using a boolean…

Accepted and it stores either a 0 or 1 in postgres which is good.

It displays ‘true’ or ‘false’ on screen and I would much rather have it
display ‘yes’ or ‘no’

How do I change the display of that boolean? Is there a helper or do I
have to write it? Can I write it so that I can refer to it again and
again with other booleans?

Craig


#6

Craig W. wrote:

On Sun, 2006-02-12 at 18:50 -0700, Pat M. wrote:

First of all for this case it’d probably be best just to make it a
boolean. It’ll lead to natural code, like

if ticket.open?

Well, if open/closed is all I wanted to deal with, yes. We’ll see.

It displays ‘true’ or ‘false’ on screen and I would much rather have it
display ‘yes’ or ‘no’

How do I change the display of that boolean? Is there a helper or do I
have to write it? Can I write it so that I can refer to it again and
again with other booleans?

The simplest way would be: ( ticket.open? ? ‘yes’ : ‘no’ )


#7

On Mon, 2006-02-13 at 03:25 +0100, Jake J. wrote:

It displays ‘true’ or ‘false’ on screen and I would much rather have it
display ‘yes’ or ‘no’

How do I change the display of that boolean? Is there a helper or do I
have to write it? Can I write it so that I can refer to it again and
again with other booleans?

The simplest way would be: ( ticket.open? ? ‘yes’ : ‘no’ )


works for me - thanks

Craig