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]

Répondre à