Concernant ton gist une recommandation, évite de faire des classes qui héritent 
de Struct.new.
Ça crée déjà une classe donc tu ajoutes une niveau inutile.

Tu peux faire ceci à la place:

MaClasse = Struct.new(:a, :b) do
  def plop
    "toto"
  end
end

Pour le reste question de point de vue, je trouve qu'on a plus de fierté à 
faire notre travail du mieux qu'on peut ;)  

Simon Courtois


On Monday 3 June 2013 at 21:29, Guirec Corbel wrote:

> J'ai fait un gist avec ma solution : https://gist.github.com/GCorbel/5699834. 
> Je penses que je suis content avec ça.
>  
> Tout de même, c'est pas facile de vouloir faire son métier comme il faut. Ha 
> que j'étais bien quand je faisais du PHP pourri qui bugait tout le temps et 
> qui n'avait aucune architecture mais que je m'en foutais. C'est une grosse 
> prise de tête de vouloir toujours faire au mieux. Je ne suis jamais sûre 
> d'avoir fait du bon code...
>  
>  
> Le 3 juin 2013 13:07, Simon Courtois <[email protected] 
> (mailto:[email protected])> a écrit :
> > C'est un edge case et selon moi dans le cas du remplacement de DCI par 
> > SimpleDelegator il ne s'applique pas plus que ça.
> > Cela dit, si on est est dans une situation de "contexte" ça me choquerait 
> > pas que InfravisionPotionModule implémente un "observe" décoré.
> > Au final c'est ce que je fais dans Draper quand j'en ai besoin.
> >  
> > Pour le reste, je pense que tu as raison de rester sur des Service objects, 
> > c'est une bonne façon de fonctionner.  
> >  
> > Bonne journée,
> >  
> >  
> >  
> > Simon Courtois
> >  
> >  
> > On Monday 3 June 2013 at 18:59, Guirec Corbel wrote:
> >  
> > > Simon, As-tu vu ça : 
> > > http://devblog.avdi.org/2012/01/31/decoration-is-best-except-when-it-isnt/?
> > >  Il peut y avoir quelques soucis à utiliser SimpleDelegator.
> > >  
> > > Je pense que je vais continuer à faire comme je fais. Mettre de la 
> > > logique dans le contrôleur et utiliser des services objects quand il y a 
> > > un logique un peu plus complexe. À chaque fois qu'il y a besoin de 
> > > callbacks il est mieux de le remplacer par un service object. Si jamais 
> > > j'ai besoin d'utiliser un héritage je ferais un rôle à la place.
> > >  
> > > Un exemple de code que j'aime bien :
> > >  
> > > class MessagesController < InheritedResource::Base
> > >   def create
> > >     sender = User.find(params[:send_id])
> > >     receiver = User.find(params[:receiver_id])
> > >  
> > >     notifier = MessageNotifier.new(sender, receiver)
> > >     notifier.call
> > >  
> > >     MessageGeocoder.new(notifier.message).call
> > >  
> > >     create!
> > >   end
> > > end
> > >  
> > > class MessageNotifier < Struct.new(:sender, :receiver, :message)
> > >   def self.call(sender, receiver)
> > >     MessageNotifier.new(sender, receiver).call
> > >   end
> > >  
> > >   def call
> > >     receiver.extend(CollectorRole)  
> > >     #traitement
> > >   end
> > > end
> > >  
> > > class MessageGeocoder < Struct.new(:message)
> > >   def self.call(message)
> > >     MessageGeocoder.new(message).call  end
> > >  
> > >   def call
> > >     #traitement
> > >   end
> > > end
> > >  
> > > module CollectorRole
> > >   def paintings
> > >     #find paintings
> > >   end
> > > end
> > >  
> > > Je crois que c'est propre. Ça serait facile de factoriser la méthode 
> > > "self.call". La différence entre un service object et un context c'est 
> > > que j'ai l'impression que le context doit prendre tout le traitement 
> > > faire dans l'action d'un contrôleur. Un service object fait quelque chose 
> > > de plus petit et on peut en utiliser plusieurs par action.
> > >  
> > > Ça reste facile à comprendre et a tester. Je ne me sens pas tyranniser 
> > > par le DCI. Avec le DCI ça m'aurait gêner d' utiliser "@user = User.all" 
> > > dans un contrôleur. Avec un service object je fais ce que je veux.
> > >  
> > > Vous en pensez quoi?
> > >  
> > >  
> > > Le 3 juin 2013 12:00, Olivier El Mekki <[email protected] 
> > > (mailto:[email protected])> a écrit :
> > > > Hello,
> > > >  
> > > > Personnellement, dans le DCI, l'idée d'avoir des méthodes disponibles
> > > > sur le model uniquement lorsqu'on en a besoin m'intéresse peu : ça
> > > > m'intéresse que mon code soit lisible, donc je vais utiliser des modules
> > > > ou des concerns, mais peu m'importe que des méthodes soient disponibles
> > > > sur mon instance alors qu'elle n'en a pas besoin.
> > > >  
> > > > Le concept de context m'a en revanche beaucoup plus séduit, notamment
> > > > parce qu'il me permet de sortir de l'enfer du STI et permet de résoudre
> > > > des problèmes que le STI lui-même ne permet pas de résoudre. J'utilise
> > > > aujourd'hui quotidiennement des contextes via cette implémentation :
> > > > https://gist.github.com/oelmekki/474dcc99649a82986dc3
> > > >  
> > > > L'idée est de faire gérer les validations, filtrages de paramètres et
> > > > before / after save (qui seraient conditionnels) par une classe dédiée.
> > > > Ça permet d'éviter d'avoir deux models (ou plus) pour gérer des
> > > > validations spécifiques de ce qui est finalement une seule resource.
> > > > Ça permet également de prendre en compte ce principe de rôle (sans
> > > > toutefois nécessiter que le rôle soit définit dans une classe, dans
> > > > mon implémentation). Parce qu'après tout, lorsqu'un admin edit un
> > > > utilisateur, ce n'est pas la même chose que lorsqu'un utilisateur
> > > > s'edite lui même (pas les mêmes validations, pas les mêmes callbacks,
> > > > pas les mêmes attributs autorisés, etc).
> > > >  
> > > > La documentation inclue dans ce fichier en dit plus long.
> > > >  
> > > > Et effectivement, pas question de forcer son usage dans toutes les
> > > > actions : on doit pouvoir faire un `Foo.all` si c'est tout ce qui
> > > > est nécessaire :)
> > > >  
> > > > Note : pour exécuter ce code, il faut utiliser active_record,
> > > > strong_parameters et cette lib :
> > > > https://gist.github.com/oelmekki/4a82dce1d9c2a5d66936
> > > >  
> > > > On 10:40 Mon 03 Jun     , Guirec Corbel wrote:
> > > > > Bonjour à tous,
> > > > >
> > > > > J'ai lu quelques trucs à propos du DCI (Data Context Integration) et 
> > > > > je ne
> > > > > sais pas quoi en penser. J'aimerais avoir votre avis sur la question.
> > > > >
> > > > > Pour ceux qui ne connaissent pas, je vous conseil de lire ceci :
> > > > > http://mikepackdev.com/blog_posts/24-the-right-way-to-code-dci-in-ruby.
> > > > >
> > > > > J'aime bien le concept de rôle. Dans l'application que je fais j'ai 
> > > > > des
> > > > > utilisateurs et un type d’utilisateur spécial, le collectionneur. Si 
> > > > > j'ai
> > > > > bien compris le concept il faut écrire un role comme ceci :
> > > > >
> > > > > module CollectorRole
> > > > >   def paintings
> > > > >     Painting.where(user_id: self.id (http://self.id))
> > > > >   end
> > > > > end
> > > > >
> > > > > Et pour avoir toutes les peintures d'un collectionneur je pourrais 
> > > > > faire
> > > > > ceci :
> > > > >
> > > > > user = User.new
> > > > > user.extend CollectorRole
> > > > > user.paintings
> > > > >
> > > > > Je n'aurais donc que deux modèles minimaux, User et Painting, 
> > > > > représentant
> > > > > uniquement les données (présente dans la base donnée). Si je veux 
> > > > > ajouter
> > > > > un comportement à mon utilisateur je l'ajouterai dans un rôle. Je 
> > > > > respect
> > > > > donc plus facilement le SRP (Single Responsability Principle). Ça 
> > > > > remplace
> > > > > un héritage.
> > > > >
> > > > > Là ou j'ai du mal c'est au niveau du context et du contrôleur. Un 
> > > > > exemple
> > > > > qui fonctionne pas trop mal serait dans le cas ou je voudrais faire 
> > > > > une
> > > > > fonctionnalité qui permet aux utilisateurs de contacter les
> > > > > collectionneurs. Je ferais un truc du genre :
> > > > >
> > > > > class UserContactCollectorContext
> > > > >   attr_reader :user_from, user_to
> > > > >
> > > > >   def self.call(user_from, user_to)
> > > > >     UserContactCollectorContext.new(user_from, user_to).call
> > > > >   end
> > > > >
> > > > >   def initialize(user_from, user_to)
> > > > >     @user_from, @user_to = user_from, user_to
> > > > >     @user_to.extend CollectorRole
> > > > >   end
> > > > >
> > > > >   def call
> > > > >     @paintings = @user_to.paintings
> > > > >     # traitement et envoi du mail
> > > > >   end
> > > > > end
> > > > >
> > > > > Et dans mon contrôleur j'aurais ceci :
> > > > >
> > > > > class MessagesController < ApplicationController
> > > > >   def send_message_to_collector
> > > > >     UserContactCollectorContext.call(User.find(params[:user_from]),
> > > > > User.find(params[:user_to]))
> > > > >   end
> > > > > end
> > > > >
> > > > > Ce code me convient. Là ou ça ne me convient pas c'est quand je veux 
> > > > > tout
> > > > > simplement la liste des utilisateurs. Il faudrait faire un contrôleur 
> > > > > du
> > > > > genre :
> > > > >
> > > > > class UsersController < ApplicationController
> > > > >   def index
> > > > >     @users = UserAllContext.call
> > > > >   end
> > > > > end
> > > > >
> > > > > Il y a un exemple similaire ici :
> > > > > https://github.com/randx/rails-dci-example/blob/master/app/controllers/documents_controller.rb
> > > > >
> > > > > Franchement, créé un context pour chaque action de ce type je trouve 
> > > > > que
> > > > > c'est trop. C'est plus simple de faire "@users = User.all". L'avantage
> > > > > c'est que ça sépare vraiment la logique. Le contrôleur n'a pas à 
> > > > > savoir ce
> > > > > que fait le context. S'il y a un mail envoyé, un géocodage ou tout le
> > > > > reste, le contrôleur ne le sait pas. C'est vraie pour l'inverse. Le 
> > > > > context
> > > > > ne sait pas ce que fait le contrôleur. On a donc un séparation franche
> > > > > entre la logique métier et la partie système.
> > > > >
> > > > > J'ai lu le livre CleanRuby. Je penses que Jim Gay va trop loin. Il 
> > > > > créé un
> > > > > context "framework agnostic" qui appel des fonctions du contrôleur. 
> > > > > J'ai du
> > > > > mal à comprendre pourquoi il écrit un livre prônant la valeur du 
> > > > > "Skinny
> > > > > Controller" alors qu'il a du code comme ceci :
> > > > > https://github.com/radiant/radiant/blob/master/app/models/page.rb.
> > > > >
> > > > > Qu'en pensez-vous? Est-ce que quelqu'un d'entre vous à mis en 
> > > > > pratique ce
> > > > > concept? Quels sont vos impressions?
> > > > >
> > > > > Merci à tous!
> > > > >
> > > > > --
> > > > > --
> > > > > 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] 
> > > > > (mailto:[email protected])
> > > > > Pour résilier votre abonnement envoyez un e-mail à l'adresse 
> > > > > [email protected] 
> > > > > (mailto:[email protected])
> > > > > ---
> > > > > Vous recevez ce message, car vous êtes abonné au groupe Google 
> > > > > Groupes Railsfrance.
> > > > > Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le 
> > > > > concernant, envoyez un e-mail à l'adresse 
> > > > > [email protected] 
> > > > > (mailto:railsfrance%[email protected]).
> > > > > Pour plus d'options, visitez le site 
> > > > > https://groups.google.com/groups/opt_out .
> > > > >
> > > > >
> > > >  
> > > >  
> > > > --
> > > > Olivier El Mekki.
> > > >  
> > > > --
> > > > --
> > > > 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] 
> > > > (mailto:[email protected])
> > > > Pour résilier votre abonnement envoyez un e-mail à l'adresse 
> > > > [email protected] 
> > > > (mailto:[email protected])
> > > > ---
> > > > Vous recevez ce message, car vous êtes abonné au groupe Google Groupes 
> > > > Railsfrance.
> > > > Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le 
> > > > concernant, envoyez un e-mail à l'adresse 
> > > > [email protected] 
> > > > (mailto:railsfrance%[email protected]).
> > > > Pour plus d'options, visitez le site 
> > > > https://groups.google.com/groups/opt_out .
> > > >  
> > > >  
> > >  
> > > --  
> > > --  
> > > 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] (mailto:[email protected])
> > > Pour résilier votre abonnement envoyez un e-mail à l'adresse 
> > > [email protected] 
> > > (mailto:[email protected])
> > > ---  
> > > Vous recevez ce message, car vous êtes abonné au groupe Google Groupes 
> > > Railsfrance.
> > > Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le 
> > > concernant, envoyez un e-mail à l'adresse 
> > > [email protected] 
> > > (mailto:[email protected]).
> > > Pour plus d'options, visitez le site 
> > > https://groups.google.com/groups/opt_out .
> > >   
> > >   
> >  
> > --  
> > --  
> > 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] (mailto:[email protected])
> > Pour résilier votre abonnement envoyez un e-mail à l'adresse 
> > [email protected] 
> > (mailto:[email protected])
> > ---  
> > Vous recevez ce message, car vous êtes abonné au groupe Google Groupes 
> > Railsfrance.
> > Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le 
> > concernant, envoyez un e-mail à l'adresse 
> > [email protected] 
> > (mailto:railsfrance%[email protected]).
> > Pour plus d'options, visitez le site 
> > https://groups.google.com/groups/opt_out .
> >   
> >   
>  
> --  
> --  
> 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] (mailto:[email protected])
> Pour résilier votre abonnement envoyez un e-mail à l'adresse 
> [email protected] 
> (mailto:[email protected])
> ---  
> Vous recevez ce message, car vous êtes abonné au groupe Google Groupes 
> Railsfrance.
> Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le 
> concernant, envoyez un e-mail à l'adresse 
> [email protected] 
> (mailto:[email protected]).
> Pour plus d'options, visitez le site https://groups.google.com/groups/opt_out 
> .
>   
>   

-- 
-- 
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 recevez ce message, car vous êtes abonné au groupe Google Groupes 
Railsfrance.
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, 
envoyez un e-mail à l'adresse [email protected].
Pour plus d'options, visitez le site https://groups.google.com/groups/opt_out .


Répondre à