6
votes

Question de style rubis: stocker la constante de hasch avec différentes valeurs possibles

C'est plus une question de style, je me demande quelles autres personnes font.

Disons que j'ai un champ dans ma base de données appelé "statut" pour un poteau de blog. Et je veux que cela ait plusieurs valeurs possibles, comme "projet", "En attente d'examen" et "posté", tout comme un exemple.

évidemment nous ne voulons pas "Code Hard" dans ces Valeurs magiques à chaque fois, cela ne serait pas sec.

Alors, ce que je fais parfois est quelque chose comme ceci: xxx

puis je peux écrire le code référoir à elle plus tard comme status [: brouillon] ou post :: Statut [: brouillon] etc.

Cela fonctionne bien, mais il y en a quelques-uns choses que je n'aime pas à ce sujet.

  1. Si vous avez une faute de frappe et appelez quelque chose comme Statut [: quelque chose_that_does_not_exist] Il ne jettera pas une erreur, il retourne simplement nul et peut finaliser cela dans la base de données, etc. avant de vous jamais remarquer un bug
  2. Il n'a pas l'air propre ni rubis-ish pour écrire des choses comme si quelque_var == Post :: Statut [: Draw] ...

    Je ne sais pas, quelque chose me dit qu'il y a une meilleure façon, mais je voulais juste voir ce que font les autres. Merci!


0 commentaires

6 Réponses :


2
votes

Vous pouvez utiliser une méthode de classe pour soulever une exception sur une clé manquante: xxx

potentiellement, vous pouvez également utiliser cette méthode pour stocker les statuts comme entiers dans la base de données en changeant vos chaînes. aux entiers (dans le hachage), convertir vos types de colonne et ajouter un getter et un setter.


0 commentaires

6
votes

Ceci est un problème courant. Considérez quelque chose comme ceci:

class Post < ActiveRecord::Base
  symbolize :status
end


0 commentaires

1
votes

Je le fais comme ceci:

class Post
  DRAFT = "draft"
  AWAITING_REPLY = "awaiting reply"
  POSTED = "posted"
  STATUSES = [DRAFT, AWAITING_REPLY, POSTED]

  validates_inclusion_of :status, :in => STATUSES
  ...
end


1 commentaires

Je l'aime, sauf que vous devez ensuite vous y référer plus tard comme Status [0] non? Dans ce cas, ce n'est pas tout aussi lisible.



9
votes

Vous pouvez utiliser HASH.NEW et lui donner un argument de bloc appelé si une clé est inconnue.

irb(main):007:0> Post::STATUS[ :draft ]
=> "draft"
irb(main):008:0> Post::STATUS[ :bogus ]
RuntimeError: Key bogus is unknown
    from (irb):2
    from (irb):8:in `call'
    from (irb):8:in `default'
    from (irb):8:in `[]'
    from (irb):8


1 commentaires

J'aime cette méthode. Pas de dépendances externes.



1
votes

Jetez un coup d'oeil au attribut_mapper gemme.

Il y a un Article associé qui montre comment vous pouvez gérer le problème de manière prétendante, comme celle-ci ( emprunté à l'article): xxx

... qui a l'air plutôt élégant.


1 commentaires

Plutôt cool. C'est dommage qu'il ne les regarde pas au cas où vous auriez plusieurs attributs, comme Statut [: projet] vs quelque chose_else [: brouillon] mais globalement, cela pourrait être la meilleure solution que j'ai vue



0
votes

Même s'il s'agit d'un ancien poste, vous pouvez utiliser la fetch strong> méthode sur hachage, qui soulève une erreur (lorsqu'il n'y a pas de valeur par défaut) si la clé donnée n'est pas trouvée.

STATUS = {
  :draft => "draft",
  :awaiting_review => "awaiting review",
  :posted => "posted"
}

STATUS.fetch(:draft) #=> "draft"
STATUS.fetch(:invalid_key) #=> KeyError: key not found: invalid_key


0 commentaires