Forum: Rails France Modele avec condition systématique

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Samuel DECHOMETS (Guest)
on 2007-01-23 16:24
(Received via mailing list)
Bonjour à tous,

Tout est dans le titre ou presque. Je voudrais savoir s'il y a moyen de
faire un model avec une condition toujours valable. J'ai une table
"produits" et je ne voudrais voir que les produits "exportés"
quelquesoit la
requête find lancée dans le controller. J'ai d'abord pensé à faire une
vue
avec la condition where qui va bien, mais c'est pas très Rails...

Merci
Nicolas C. (Guest)
on 2007-01-23 16:42
(Received via mailing list)
Le 23 janv. 07 à 15:22, Samuel DECHOMETS a écrit :

> Bonjour à tous,

Salut,

> Tout est dans le titre ou presque. Je voudrais savoir s'il y a
> moyen de faire un model avec une condition toujours valable. J'ai
> une table "produits" et je ne voudrais voir que les produits
> "exportés" quelquesoit la requête find lancée dans le controller.
> J'ai d'abord pensé à faire une vue avec la condition where qui va
> bien, mais c'est pas très Rails...

Ton bonheur se trouve dans with_scope :

Product.with_scope :find => { :conditions => [ 'state = ?',
'exported' ] } do
   Product.find(:all)
end
--
Nicolas C.
http://www.bounga.org
http://www.cavigneaux.net
Guillaume G. (Guest)
on 2007-01-23 18:00
(Received via mailing list)
Tu peut surcharger le find de ton model et faire en sorte de merger
n'importe quel condition avec quelque chose un peut comme cela

:conditions => [ 'state = ?',
'exported' ]

J'ai pas ma machine sous la main pour faire un exmeple et tester mais on
devrait pouvoir faire quelque chose comme cela.

Voila HTH.
Samuel DECHOMETS (Guest)
on 2007-01-23 18:08
(Received via mailing list)
Le 23/01/07, Nicolas C. <removed_email_address@domain.invalid> a écrit :
> > "exportés" quelquesoit la requête find lancée dans le controller.
> Nicolas C.
> http://www.bounga.org
> http://www.cavigneaux.net


Merci Nicolas, mais ce n'est pas exactement ce que je cherche.
D'ailleurs j'ai un peu de mal à voir l'intérêt du with_scope dans cet
exemple par rapport à un  Product.find(:all,:conditions=> [ 'state = ?',
'exported' ]) ?
En fait, j'utilise des lib qui gèrent les find et je ne peux pas
"encapsuler" ces find dans un with_scope à moins de hacker les libs en
questions, ce dont je n'ai pas très envie.
J'aurais préféré un truc du style :

class ProduitExportesController < ApplicationController
  model :product, :conditions=> [ 'state = ?', 'exported' ]
  use_ma_lib

end

module ma_lib
 self.included(base)
   super
   base.extend(ClassMethods)
 end
 module ClassMethods
  def use_ma_lib
   def foo1
   ...find(:all)...
   end
   def foo2
   ...find(:all)...
   end
  end
 end
end

Avec les find(:all) de ma_lib prenant bien sûr en compte la condition [
'state = ?', 'exported' ]

J'espère avoir été clair, j'aurais dû apporter plus de précision sur mon
premier post ;)

Samuel
Renaud Morvan (Guest)
on 2007-01-23 22:19
(Received via mailing list)
Le 23 janv. 07 à 17:06, Samuel DECHOMETS a écrit :

> > moyen de faire un model avec une condition toujours valable. J'ai
> end
> "encapsuler" ces find dans un with_scope à moins de hacker les libs
>  self.included(base)
>    end
>   end
>  end
> end
>
> Avec les find(:all) de ma_lib prenant bien sûr en compte la
> condition [ 'state = ?', 'exported' ]
>
> J'espère avoir été clair, j'aurais dû apporter plus de précision
> sur mon premier post ;)
>

Concrètement il n'y a pas d'outil build-in pour faire ca mais tu peux
le faire à la main car il y a tout ce qu'il faut dans rails.

Le plus simple est effectivement de surcharger les methodes en
question, la nature ultra dynamique de ruby fait qu'il n'y a pas de
raison que tu ne puisses pas utiliser ce mécanisme.

Mais si vraiment tu veux éviter tu peux jouer directement avec les
mécanismes de scope de rails.

Il faut savoir que rails stocke le scope dans une variable de class
accessible par la méthode protected scoped_methods. La bonne nouvelle
c'est que Rails se paye le luxe de faire en sorte que ce soit thread
safe.

L'astuce consiste à charger au moment de l'instanciation du
controlleur cette methode scoped_methods avec le scope qui va bien.

Attention cependant car c'est un tableau et pour éviter de rajouter
3000 fois le même scope il faut le netoyer (typiquement au moment du
paramétrage de scope_methods).

Une implémentation possible est de rajouter une methode static à ta
class qui ferait en gros

class Model
  class << self
    def bind_to_scope
      self.unbind
      self.scoped_methods << TON_SCOPE
    end

    def unbind
      self.scoped_methods.clear
    end
  end
end

et un before filter dans l'application controller qui se contente de
faire un Model.bind_to_scope.

Renaud
Samuel DECHOMETS (Guest)
on 2007-01-24 01:02
(Received via mailing list)
Super,

Merci à tous les  2 pour m'avoir fait decouvrir le "scope". Dans mon cas
la
méthode static proposée par Renaud convient parfaitement.
Ceci dit on ne m'enlevera pas de l'idée qu'il serait intéressant de
pouvoir
faire des "vues" (au sens SQL du terme) sur des modeles. Compte tenu du
fait
que la vue SQL n'est pas dans la philosophie Rails pk ne pas pouvoir le
faire sur un modele Rails (sans avoir à  charger des methodes protected,
j'entends...).
Pour reprendre mon exemple il serait plus simple et plus clair de coder
dans
le controller :
model :product(:conditions=> [ 'state = ?', 'exported' ], :include =>
:gamme...)

L'astuce proposée par Renaud va bien dans ce sens mais ce n'est pas le
genre
d'aide que l'on peut trouver dans la doc en ligne ou les bouquins...

Samuel
This topic is locked and can not be replied to.