Je vais ajouter mes deux cents également.

Pourquoi n'ajoutes tu pas un événement persistant à la création de
l'événement "naissance" plutôt que de l'ajouter "à la volé"?
Personnellement, plutôt que d'utiliser un callback, je ferais une classe du
type `EventCreator` avec un méthode `call` qui sauvegardera l'événement
avec une condition si c'est un événement de type début. Tu pourrais
également ajouter une méthode `save_with_subevents` à ta classe `Event`
pour lui donner la responsabilité.

Par exemple :

class EventCreator
  def initialize(event_params)
    ...
  end

  def call
    event = Event.new(event_params)
    event.save_with_subevents
  end
end

class Event
  def save_with_subevent
    if save && event.type == BORN
      event.story.events.create(#....)
    end
  end
end

Tu pourrais également créer une méthode `add_event` à `Story` comme ceci

class Story
  def add_event(event)
    events << event
    if event.type == Event::BORN
      events.create(#....)
    end
  end
end

Qu'en pensez vous?


Le 2 septembre 2014 10:34, Thibault Jouan <[email protected]> a écrit :

> On 2014-09-01 23:02:49 +0200, Guillaume Betous wrote:
> > Dans le story_controler :
> >
> > def show
> >   @events = @story.compute_events
> > end
> >
> > Dans le modèle :
> >
> > def compute_events
> >   events = self.events
> >   events.each do |e|
> >     if e.name == "naissance"
> >       x = Event.new(:name => "majeur", :date => e.date + 18.years)
> >       events << x
> >     end
> >   end
> >   return events
> > end
>
>   Il faudrait connaître l'implémentation de events#each et events#<<
> pour mieux comprendre, cela dit, deux lignes ne me paraissent pas
> intuitives :
>
> >   events = self.events
>
>   Le `self.' me semble inutile, et au final tu assignes une variable
> nommée identiquement à une méthode, ça pourrait porter à confusion.
>
> >   events.each do |e|
> […]
> >       events << x
>
>   Du fait de la première ligne de la méthode, je suis confus sur
> l'intention :-) Quel que soit le code dans #each et #<<, ça me parait
> non trivial de modifier l'état d'un objet pendant que tu le parcours,
> pas impossible bien sûr, mais pas forcément intuitif.
>
>
>   Approche différente qui me vient en tête (pas beaucoup testée) :
>
>
> class Story
>   def initialize(*events)
>     @events = events
>   end
>
>   def compute_events
>     @events.inject([]) { |m, e| m.push e, *yield(e) }
>   end
> end
>
> p Story.new(:foo, :bar).compute_events { |e| :baz if e == :bar }
> => [:foo, :bar, :baz]
>
>
>   Je passe la logique de nouvel événement sous forme de bloc, mais
> rien n'empêche d'utiliser une classe ou juste proc/lambda :
>
> SOME_EVENT_GENERATOR = ->(e) { Event.new(name: '', …) if e.birth? }
>
> story.compute_events &SOME_EVENT_GENERATOR
>
>   Si vraiment Story doit couvrir la responsabilité de la génération
> d'évènement, je l'implémenterais dans des méthodes privées, mais dans
> ce dernier cas Story devient fortement couplé à un event. Il y aurait
> aussi la piste d'implémenter un event#generate_events si c'est son
> rôle.
>
>
> --
> Thibault Jouan
>
> --
> --
> 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/d/optout .
>

-- 
-- 
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/d/optout .

Répondre à