Guillaume, est-ce ce fonctionnement que tu cherches?

https://gist.github.com/712202

2010/11/23 guillaume <[email protected]>

> Quand je dis gros c'est plus pour dire qu'il passe tout le temps
> dedans et donc que c'est lourd,
> mais je n'avais en effet pas penser à cette histoire de caching en
> mode prod/dev... vu que je suis en dev je pense que c'est bien la mon
> "pb"... du coup je vais pouvoir limiter ces passages.
>
> Après effectivement il y a moyen de réduire le nb de ligne très
> simplement comme tu le suggère...
>
> En tout cas merci !
>
> On 23 nov, 17:33, "Renaud (nel) Morvan" <[email protected]> wrote:
> > On 23 nov. 2010, at 17:16, guillaume wrote:
> >
> > > Bon finalement ma solution ne marche pas car une fois le default_scope
> > > définie, je ne peux pas revenir sur ces conditions, même avec un named
> > > scope... retour à la case départ.
> >
> > > Renaud je travail sur ta solution,
> > > donc pour le moment je fais un gros before filter sur mon application
> > > controller et après j'appel apply_language_scope sur chacun de mes
> > > modele suivant la locale de l'utilisateur.
> >
> > > C'est juste dommage de devoir le faire à chaque fois et que le scope
> > > ne soit pas sauvegarder jusqu'au prochain appel de
> > > apply_language_scope, ca serait moins lourd.
> >
> > Il l'est bien évidement sauf si tu recharges tes modèles à chaque requête
> évidemment (genre mode développement).
> >
> > Ceci dit je te déconseille de te reposer la dessus, le web est stateless
> de nature, c'est idiot de tenter de le contrarier quand ce n'est pas
> nécessaire.
> >
> > Je ne vois pas bien le problème, il n'y a pas besoin de GROS before
> filter ca se fait en quelques lignes de code avec un middlerack ou en around
> filter. Par exemple:
> >
> > Class Rack::LanguageScope
> >         def initialize(app)
> >                 @app = app
> >         end
> >
> >         def call(env)
> >                 Post.with_language(mylanguage) do
> >                         @app.call(env)
> >                 end
> >         end
> > end
> >
> > Si tu veux scoper plusieurs modèles soit tu les enchaines, soit tu
> recodes le trucs en:
> >
> > SCOPED_MODELS = [Model1, Model2, Model3]
> >
> > def call(env)
> >         SCOPED_MODELS.each &:apply_language_scope
> >         @app.call(env)
> > ensure
> >         SCOPED_MODELS.each &: reset_language_scope
> > end
> >
> > Ou si vraiment tu veux t'amuser tu peux coder ca sous la forme d'un mixin
> qui mémorise l'ensemble des classes qui l'inclue et comme ca tu n'as pas
> besoin de maintenir le tableau de classes.
> >
> >
> >
> >
> >
> >
> >
> > > Une idée la dessus ?
> >
> > > Merci.
> >
> > > On 23 nov, 13:44, guillaume <[email protected]> wrote:
> > >> Merci pour toutes ces précisions.
> > >> Pour répondre dans l'ordre :
> >
> > >> - Pour le contexte c'est une question d'internationalisation.
> > >> J'ai des modeles liés à une table "lang" qui indique si tel record est
> > >> pour du "fr", "en" etc...
> > >> Pour ne pas avoir à réécrire tout mes find pour prendre en compte la
> > >> langue de l'utilisateur via I18n.locale, je voulais utiliser le
> > >> default_scope en lui passant la valeur de I18n.locale correspondant à
> > >> l'utilisateur.
> >
> > >> - J'ai essayé de reprendre le hack de Rails 3, mais apparemment il y a
> > >> qd mm eu un certain nb de changement car après avoir réécris 3 méthode
> > >> j'ai toujours des problèmes... et comme c'est du hack de hack, je ne
> > >> suis pas très fan.
> >
> > >> - Je vais voir ce que je peux faire avec ta méthode Renaud, cependant
> > >> je ne suis pas encore super à l'aise avec les scopes.
> >
> > >> Sinon j'ai trouvé une "méthode" en mêlant default_scope et
> > >> named_scope, mais elle est très spécifique à mon cas sans être idéal.
> > >> Pour cela je set mon default_scope pour trouver que de "fr", et les
> > >> parties de mon application que je vais internationaliser (pas tout
> > >> pour commencer) je réécris mes find avec des named_scope qui seront
> > >> dynamique avec I18n et qui passeront par dessus le default_scope
> > >> défini.
> >
> > >> En tout cas déjà grand merci pour vos proposition !
> >
> > >> On 23 nov, 11:55, "Renaud (nel) Morvan" <[email protected]> wrote:
> >
> > >>> Bonjour,
> >
> > >>> Personnellement dans ce genre de cas ce que je faisais depuis Rails 1
> est de hacker directement via la méthode de classe
> ActiveRecord::scoped_methods
> >
> > >>> C'est concrètement un tableau qui fonctionne sous la forme d'un
> class_inheritable_accessor, thread safe, qui contient le scope courant du
> model. Name scope et default scope repose la dessus.
> >
> > >>> Il te suffit de créer une méthode de class ou d'instance pour
> configurer ce scope sur ton modèle que tu appelleras dans un before_filter.
> >
> > >>> class Post < ActiveRecord::Base
> > >>>         class << self
> > >>>                 def apply_language_scope(lang = :en_EN)
> > >>>                         self.scoped_methods << {:find => {:conditions
> => {:lang => lang}, :create => {:lang => lang}}
> > >>>                 end
> > >>>         end
> > >>> end
> >
> > >>> Attention cependant, il faudra déconfigurer ton scope (avant de la
> reconfigurer par exemple si il est toujours active, en around filter sinon,
> ne pas oublier le ensure).
> >
> > >>> Il doit être possible de faire ce genre de hack via le initialize du
> modèle mais globalement scoped_methods est une api stable depuis au moins
> 1.0, la seule chose qui change c'est que suivant les versions elle devient
> public/protected/private
> >
> > >>> Globalement c'est un hack de quelques lignes qui fait exactement ce
> que tu souhaites mais c'est un peu touchy car ce ne sont pas des api
> publique en Rails 2.3, il faut bien comprendre les limitations et le
> fonctionnement interne des scope en général pour gérer les effets de bords.
> >
> > >>> C'est le coeur du hack, tu peux lui donner une forme plus
> sympathique:
> >
> > >>>  class Post < ActiveRecord::Base
> > >>>         class << self
> > >>>                 def apply_language_scope(lang = :en_EN)
> > >>>                         self.scoped_methods << {:find => {:conditions
> => {:lang => lang}, :create => {:lang => lang}}
> > >>>                 end
> >
> > >>>                 def reset_language_scope
> > >>>                         self.scoped_methods.clear
> > >>>                 end
> >
> > >>>                 def with_language(lang = :en_EN)
> > >>>                         self.apply_language_scope(lang)
> > >>>                         yield
> > >>>                 ensure
> > >>>                         self.reset_language_scope
> > >>>                 end
> > >>>         end
> > >>> end
> >
> > >>> Et ton around filter se contente d'appeler with_language autour de
> l'execution de la requête
> >
> > >>> R.
> >
> > >>> On 23 nov. 2010, at 11:22, guillaume wrote:
> >
> > >>>> Bonjour à tous,
> >
> > >>>> Je souhaite utiliser un default_scope, mais le rendre dynamique pour
> > >>>> l'utiliser avec I18n.locale.
> > >>>> La seule façon de faire à priori est de lui passer un
> Proc/Lambda....
> > >>>> Malheureusement cela ne semble pas être supporté sous Rails 2, sous
> > >>>> Rails 3 certains on patché (
> https://rails.lighthouseapp.com/projects/
> > >>>> 8994/tickets/1812-default_scope-cant-take-procs) ActiveRecord pour
> le
> > >>>> faire mais difficile de le reappliquer sous Rails 2 .
> >
> > >>>> Je ne veux pas faire de named_scope pour la simple et bonne raison
> que
> > >>>> cela me ferai réécrire des centaines (voir milliers) d'appels, et
> > >>>> passer sous Rails 3 c'est également trop de boulot pour l'instant.
> >
> > >>>> Je penche depuis pas mal d'heures sur ce problème, donc si vous avez
> > >>>> des idées je grandement preneur,
> >
> > >>>> Merci.
> >
> > >>>> --
> > >>>> Vous avez reçu ce message, car vous êtes abonné au groupe
> "Railsfrance" de Google Groups.
> > >>>> Pour transmettre des messages à ce groupe, envoyez un e-mail à
> l'adresse [email protected]
> > >>>> Pour résilier votre abonnement envoyez un e-mail à l'adresse
> [email protected]
> >
> > > --
> > > Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance"
> de Google Groups.
> > > Pour transmettre des messages à ce groupe, envoyez un e-mail à
> l'adresse [email protected]
> > > Pour résilier votre abonnement envoyez un e-mail à l'adresse
> [email protected]
>
> --
> Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de
> Google Groups.
> Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse
> [email protected]
> Pour résilier votre abonnement envoyez un e-mail à l'adresse
> [email protected]
>



-- 
Franck Verrot
75 rue Paul Verlaine
69100 Villeurbanne
06 22 47 78 03

-- 
Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de 
Google Groups.
Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse 
[email protected]
Pour résilier votre abonnement envoyez un e-mail à l'adresse 
[email protected]

Répondre à