Bonjour à tous,

Désolé pour le retard de réponse. Effectivement, le problème que je posais
n'était pas clair car il n'était plus très clair dans ma tête non plus. En
voulant reformuler pour donner un exemple concret, j'ai essayé une autre
solution qui finalement était beaucoup plus simple. Je ne sais plus ou j'ai
entendu parler de "Duck quelque chose". C'est une méthode qui dit que,
quand tu as un problème, explique le, comme si tu montrais ce que t'as fait
à quelqu'un, à un canard en plastique. Bien souvent, en prenant de la
distance sur le problème et en récapitulant depuis le départ on arrive à
trouver les solutions nous-même. Merci d'avoir jouer  le rôle des canards!

Pour prendre un exemple plus concret, voici ce que je voulais faire : Pour
un site, un collectionneur d’œuvre d'art peu posséder plusieurs œuvre.
Chaque œuvre possède un prix. Le prix de l'oeuvre peut varier en fonction
d'une période. Lorsque le collectionneur prolonge la période d'affichage,
il peut changer le prix. Le nouveau prix est applicable uniquement lorsque
la première période d'affichage est terminée. Par exemple, un Picasso est
affiché jusqu'au 01/01/2014 au prix de 1000 euros. Le collectionneur décide
de prolonger de six mois l'affichage et de modifier le prix de 1500 euros.
Le prix du tableau devra être de 1000 euros d'aujourd'hui jusqu'au premier
janvier et de 1500 du premier janvier au premier juin.

Ce que je pensais faire (le solution trop compliquée) était de faire un
virtual attribute avec mes deux modèles :

class Work < ActiveRecord::Base
  has_many :prices

  def price
    prices.where("now() BETWEEN begin_date AND end_date").first.price
  end

  def price=(price)
    #assignation du prix au modèle dépendant
  end
end

class Price < ActiveRecord::Base
  attr_accessor :price, :end_date, :begin_date
end


L'idée était que le fait qu'il y ai un modèle dépendant soit transparent.
Finalement, c'est trop compliqué. Un des probème était que je ne pouvais
pas faire ceci :

work = Work.new
work.price = 123
puts work.price

Ça renvoi nil parceque ça fait une requête SQL. Après réflexion, ça ne me
sert à rien de faire ça. Je me suis cassé la tête sur un problème pour rien
parce-que je n'avais pas suffisamment de recule.

Le plus simple à été de créer un nouveau prix à chaque fois que je créer ou
modifie une œuvre avec un decorator pour que ça soit transparent pour les
vues.

Merci pour votre aide!


Le 18 octobre 2013 15:11, vala <[email protected]> a écrit :

> Salut Guirec,
>
> En fait j'ai l'impression qu'une autre approche que celle que tu essaies
> d'implémenter ici serait probablement plus efficace.
> Dans ta situation, devoir gérer des models saved et d'autres non, sur une
> relation via un delegate me semble un peu obscur : peut être qu'en
> expliquant un peu mieux le problème de base, une solution plus adaptée peut
> t'être donnée.
>
> A quel moment est-ce-que tu dois faire cette opération ?
> Quand a été créé le `second_model` auquel tu essaies d'accéder ?
> Est-ce-que tu ne peux pas y avoir accès par un autre moyen : dans un hook
> `before_…` par exemple ?
>
> Peut être d'autres auront une idée directement, mais j'ai l'impression que
> le code pourrait être simplifié avant de résoudre ce problème.
>
> Bonne soirée,
>
>
> Valentin
>
>
>
> Le 18 oct. 2013 à 20:57, Guirec Corbel <[email protected]> a écrit :
>
> > Bonjour les amis,
> >
> > Pour un projet, j'ai besoin de faire en sorte qu'un attribut ne soit pas
> changé tout de suite mais plus tard, selon une date. Pour résoudre ce
> problème, j'ai pensé à deux solutions :
> >
> > La première est de faire une délégation comme ceci :
> >
> > class MyMainClass < ActiveRecord::Base
> > has_many :second_models
> >
> > delegate :attribute, to: :second_model, allow_nil: true
> >
> > def second_model
> > second_models.where("....").last
> > end
> > end
> >
> > class SecondModel < ActiveRecord::Base
> > attr_accessor :attribute
> > end
> >
> > Ça fonctionne sauf que le second modèle doit être sauvegardé dans la
> base de données pour que ça fonctionne étant donné qu'il y a une requête
> effectuée pour le retrouver. De plus, si je fait quelque chose comme ceci :
> >
> > my_main_class.attribute = 1234
> > puts my_main_class_attribute
> >
> > Ça ne renvoie la nouvelle valeur, mais l'ancienne étant donné que je
> n'ai pas fait de `save`. Évidement, je pourrais faire un `save` à chaque
> fois que je change un attribut, mais ce n’est vraiment pas efficace et je
> commence à trouver a trop compliqué pour rien. En plus, il faudrait que je
> créé un nouveau `SecondModel` pour chaque nouveau `MyMainClass`. Pfff...
> >
> > Ma deuxième idée est de créer les deux mêmes modèles, mais de supprimer
> les relations entre `MyMainClass` et `SecondClass` et de faire une tâche
> qui passe tous les jours pour changer le champ `attribute`. Ça peut
> marcher, mais je trouve ça vraiment bizarre.
> >
> > Connaissez-vous une gem qui pourraient faire ce que je veux faire? Je
> n'en ai pas trouvé. Avez-vous d'autres solutions à proposer?
> >
> > 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 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 .
>
> --
> --
> 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 .
>

-- 
-- 
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 à