Ruby Forum Rails France > Table de paramètres

Posted by Julien Lestavel (butterhead)
on 27.04.2008 00:06
Salut,

Je développe ma première application avec Rails, et je me pose une
question d'ordre "architecturale" : j'ai de nombreux paramètres et
constantes (de différents types), dont j'ai besoin à de nombreux
endroits dans mon appli et je ne sais pas comment les gérer (en
respectant le principe DRY).

Devrais-je créer une table parameters, lié à une classe Parameter pour
cela? Si oui, quelle est ensuite la meilleure solution pour retrouver
mes paramètres : avec une recherche par id, par nom...?

je suppose qu'il doit exister une technique classique pour gérer les
divers petits paramètres, mais je ne la connais pas...

Par avance, merci.
Posted by Pierre Valade (Guest)
on 27.04.2008 10:57
(Received via mailing list)
Bonne question, dont j'aimerais aussi connaître une réponse élégante.

Personnellement, je mélange souvent des informations dans les Model
eux-mêmes (dans une méthode self.parameters qui renvoi un hash par
exemple) ou dans des tables créées pour stocker les paramètres (quand
ceux-ci doivent pouvoir être modifiés simplement).

Pierre
Posted by philippe lachaise (Guest)
on 27.04.2008 12:37
(Received via mailing list)
Si ces paramètres sont facilement stockables en YAML (pratique en 
général),
moi je me fais souvent un

lib/custom_config.rb (ex de source plus bas) et un 
config/custom_config.yml

Sinon, ces parmaètres doivent-ils être accessibles dans les modèles, les
controlleurs, les vues, partout ?
Les solutions peuvent être veriées suivant les besoins...

====================================
module CustomConfig

  @@custom_config = nil

  def custom_config( *args )
    @@custom_config ||=
YAML::load(File.open("#{RAILS_ROOT}/config/custom_config.yml"))

    if args.is_a? Array
      value = ''
      node  = @@custom_config

      args.each do |key|
        raise "Non-symbol argument in CustomConfig#custom_config() : 
#{key}
is a #{key.class.name}" unless key.is_a?( Symbol )
        if ( val = node[key.to_s] ).is_a?( String )
          value = val # Should be a string since it comes from YAML file
        else
          node = val
        end
        break if node.nil? # Specified key chain is broken
      end

      value
    else
      @@custom_config
    end
  end

end
====================================
config/custom_config.yml


contact:
  recipients: 
philippe.lachaise+balthazar_contact@gmail.com<philippe.lachaise%2Bbalthazar_contact@gmail.com>
  subject_prefix: Mnemos User Contact
  feedback: Merci d'avoir pris le temps de nous contacter ; l'équipe 
toto
vous répondra dans les plus brefs délais.

autre_chose:
  poet: vos papiers
====================================



--
IciMarché fédère l'e-commerce de proximité
http://icimarche.fr
Posted by Julien Lestavel (butterhead)
on 28.04.2008 18:07
Merci pour cette réponse.
L'idée de stocker les paramètres dans un YAML est sympa. Mais tu ne 
récupères que des Strings, que tu dois caster par la suite je suppose.
Dans mon cas, ces données doivent essentiellement être accessibles dans 
une classe qui s'occupe de certains calculs (offensant qq peu le modèle 
MVC, mais ca me permet d'alléger un peu le code du controller 
correspondant), mais j'en aurais surement besoin dans certaines vues.
ton module CustomConfig est accessible de partout c'est bien ca?
Posted by philippe lachaise (Guest)
on 28.04.2008 20:06
(Received via mailing list)
>> ton module CustomConfig est accessible de partout c'est bien ca?

Je m'aperçois que je fais
  include CustomConfig
dans application.rb, ce qui rend visible dans tous les controlleurs ; on
pourrait je pense le mettre dans environnement.rb pour l'avoir partout 
mais
j'ai pas eu le besoin donc pas testé.

--
IciMarché fédère l'e-commerce de proximité
http://icimarche.fr
Posted by Jean-Baptiste Escoyez (Guest)
on 28.04.2008 21:42
(Received via mailing list)
Bonsoir Julien,

On 28 Apr 2008, at 18:07, Julien Lestavel wrote:

> Merci pour cette réponse.
> L'idée de stocker les paramètres dans un YAML est sympa. Mais tu ne
> récupères que des Strings, que tu dois caster par la suite je suppose.

Justement, tu peux directement récupérer des Hash. Super facile à  
exploiter.
Pour le mode d'emploi détaillé : http://railscasts.com/episodes/85

> Dans mon cas, ces données doivent essentiellement être accessibles  
> dans
> une classe qui s'occupe de certains calculs (offensant qq peu le  
> modèle
> MVC, mais ca me permet d'alléger un peu le code du controller
> correspondant)

Petite parenthèse : Le contrôleurs doivent toujours être le plus léger
possible. Les calculs doivent aller dans une classe du modèle. Même si
cette classe n'est pas une classe ActiveRecord, elle fait bien partie
du modèle.

> ton module CustomConfig est accessible de partout c'est bien ca?

Oui :) re: http://railscasts.com/episodes/85


Bonne soirée,

Jean-Baptiste

--
Jean-Baptiste Escoyez
Belighted.com | Web 2.0 Consulting & Training
Email : jbe@belighted.com | Phone: +32 486 377593
Posted by philippe lachaise (Guest)
on 29.04.2008 08:23
(Received via mailing list)
>> Les calculs doivent aller dans une classe du modèle.

J'ajoute que si le champ d'application de cette algorithmique déborde un
modèle particulier, on peut très bien la partager à partir d'un module
défini dans une lib (si la réutilisation multi-app ne justifie pas un
plugin) et mixed-in (include) dans les modèles qui en ont besoin.

De cette façon on partage transversalement la logique tout en gardant un
code DRY et bien organisé.


--
IciMarché fédère l'e-commerce de proximité
http://icimarche.fr
Posted by Julien Lestavel (butterhead)
on 29.04.2008 10:35
Merci pour ces précisions. Je respectais donc les bonnes pratique Rails 
sans le savoir...
Par contre, j'ai un souci avec la solution qui consiste à charger un 
fichier yaml dans environment.rb : je définis
APP_PARAMETERS = YAML.load_file("#{RAILS_ROOT}/config/parameters.yml")
mais après cette variable globlale n'est pas accessible!
Je recois un message :
uninitialized constant MyController::APP_PARAMETERS

Vous croyez que ca peut être dû à ma version de Rails (1.2.3). C'est 
étrange car la variable RAILS_GEM_VERSION = '1.2.3' unless defined? 
RAILS_GEM_VERSION, défini dans le même environment.rb est accessible 
partout, elle.

Vous voyez où pourrait se situer le problème?
Posted by Julien Lestavel (butterhead)
on 29.04.2008 10:48
Excusez-moi, j'ai posté trop vite! Je n'avais pas relancé mon WEBrick, 
donc la constante n'était pas initialisée...

Julien Lestavel wrote:
> Merci pour ces précisions. Je respectais donc les bonnes pratique Rails 
> sans le savoir...
> Par contre, j'ai un souci avec la solution qui consiste à charger un 
> fichier yaml dans environment.rb : je définis
> APP_PARAMETERS = YAML.load_file("#{RAILS_ROOT}/config/parameters.yml")
> mais après cette variable globlale n'est pas accessible!
> Je recois un message :
> uninitialized constant MyController::APP_PARAMETERS
> 
> Vous croyez que ca peut être dû à ma version de Rails (1.2.3). C'est 
> étrange car la variable RAILS_GEM_VERSION = '1.2.3' unless defined? 
> RAILS_GEM_VERSION, défini dans le même environment.rb est accessible 
> partout, elle.
> 
> Vous voyez où pourrait se situer le problème?
Posted by philippe lachaise (Guest)
on 29.04.2008 12:55
(Received via mailing list)
>> environment.rb : je définis APP_PARAMETERS =
YAML.load_file("#{RAILS_ROOT}/config/parameters.yml")

>> cette variable globlale n'est pas accessible! .... uninitialized constant
MyController::APP_PARAMETERS

>> cette variable globlale n'est pas accessible!

En fait ce n'est pas une variable globale (elle serait préfixée par $).

Ruby la cherche dans le scope de MyController alors qu'elle est définie 
dans
un autre scope (lequel au fait, j'ai un trou ?)

Mais APP_PARAMETERS n'est pas utile si tu utilises directement la 
méthode
"custom_config". Ce n'est pas pénalisant car le chargement n'a lieu que 
la
première fois :

@@custom_config ||=
YAML::load(File.open("#{RAILS_ROOT}/config/custom_config.yml"))

(l'opérateur ||= s'en assure)

--
IciMarché fédère l'e-commerce de proximité
http://icimarche.fr