Forum: Rails France Creation de sous_items en meme temps qu'un item

Posted by Arnaud Lec (moustach)
on 2009-06-22 11:41
Bonjour,

je ne savais pas trop quoi mettre comme titre alors je vais expliquer ce
sera plus clair.

Actuellement je doit creer une application qui va referencer des
produits. A chaque produits, on pourra lui attacher des composants. Il
faudrait que l'attachement de composants puisse s'effectuer en meme
temps que la creation du produit (ce qui parait logique a mon sens)

En gros dans la vue NEW de Products, il faut au début avoir 1 composant
minimum obligatoire. La pas de probleme j'ai su le faire.
Mais apres il me faut pouvoir en creer autant que je le desire pour un
seul produit. J'ai pour cela une table pour les composants, une table
pour les produits et une table de liaison entre les tables composants et
produits.

Pour pouvoir creer un produit en meme temps qu'associer un composant a
ce produit, j'ai fait comme ca :

======= View : products/new =======
<% form_for(@product) do |f| %>
  <fieldset>
    <legend>New Product</legend>
    <%= f.error_messages %>
    <p class="ligne_input">
      <%= f.label :name %>
      <%= text_field_with_auto_complete :product, :name,{}, :skip_style
=> false, :autocomplete => false %>
    </p>
....

    <div id="components">
      <p class="ligne_input">
        <%= label :products_component, :component_id %>
        <%= collection_select(:products_component, :component_id,
Component.all, :id, :name, { :prompt => "- Choose Component"}) %>

        <%= label :products_component, :quantity %>
        <%= text_field :products_component, :quantity %>
      </p>
    </div>
....


======= Products_controller =======
def create
  @product = Product.new(params[:product])
    respond_to do |format|
      if @product.save
        @product_component =
ProductComponent.new(params[:product_component])
        @product_component.product_id = @product.id
        if @product_component.save
          flash[:notice] = 'Product was successfully created.'
          format.html { redirect_to(@product) }
          format.xml  { render :xml => @product, :status => :created,
:location => @product }
        else
          @product.destroy
          format.html { render :action => "new" }
          format.xml  { render :xml => @product.errors, :status =>
:unprocessable_entity }
        end
      end
    end
  end


Il faudrait selon moi mettre le contenu de la div components dans un
partial et avec un bouton (+) sur la ligne rajouter la partial une fois
en dessous.
Et ensuite je ne sais pas comment traiter le cas de multiples components
dans mon controller.

Si quelqu'un a une idee, ca m'interesse car la je seche. A moins de
nommer les params differement a chaque fois mais je ne sais pas comment
faire ca dans la partial et deviner pour recuperer les donnees ensuite
Posted by Fernando Perez (fernando)
on 2009-06-22 14:53
Si chaque composant est unique à un produit, alors 
accepts_nested_attributes_for est parfait.

Si par contre tu souhaites créer des composants en même temps que ton 
produit et ensuite que ces composants soient réutilisés par d'autres 
produits, les choses vont se gâter sérieusement.

Poses toi la question de savoir s'il ne vaut pas mieux sur une page 
créer tous les composants nécessaires, et sur une autre page assembler 
les composants pour faire un produit, parce que déjà ça tu vas t'amuser, 
cf. mon message: http://www.ruby-forum.com/topic/189970
Posted by Arnaud Lec (moustach)
on 2009-06-22 15:28
Fernando Perez wrote:
> Si chaque composant est unique à un produit, alors 
> accepts_nested_attributes_for est parfait.
> 
> Si par contre tu souhaites créer des composants en même temps que ton 
> produit et ensuite que ces composants soient réutilisés par d'autres 
> produits, les choses vont se gâter sérieusement.
> 
> Poses toi la question de savoir s'il ne vaut pas mieux sur une page 
> créer tous les composants nécessaires, et sur une autre page assembler 
> les composants pour faire un produit, parce que déjà ça tu vas t'amuser, 
> cf. mon message: http://www.ruby-forum.com/topic/189970

Effectivement accept_nested_attributes_for serait une solution sauf que 
je suis sur Rails 2.2 qui apparemment n'implémente pas la fonction.

Sinon je suis dans le 2eme cas. Les components sont des pièces utilisées 
par le produit mais ces pièces peuvent servir à d'autres produits.
Posted by Arnaud Lec (moustach)
on 2009-06-22 15:31
J'ai appuyer trop vite sur envoyer

Sinon pour le truc de créer d'un coté un produit, d'un autre coté des 
composants et sur une 3ème vue de faire l'association ça fonctionne déjà 
comme ça à la base.

Mais ça va être le bordel pour l'utilisateur si à partir d'une liste de 
components il ne peux pas créer son produit et les composants utilisé 
dans le produit. (Les composants sont crées à l'avance de toute façon. 
La liste est disponible)
Posted by Fernando Perez (fernando)
on 2009-06-22 21:42
Arnaud Lec wrote:
> J'ai appuyer trop vite sur envoyer
> 
> Sinon pour le truc de créer d'un coté un produit, d'un autre coté des 
> composants et sur une 3ème vue de faire l'association ça fonctionne déjà 
> comme ça à la base.
Un bon coup à faire: tu gardes tes controlleurs séparés pour gérer la 
création du produit et des composants, sauf que la unique que 
l'utilisateur voit tu fais tes post en ajax, comme ça dans la même page 
l'utilisateur peut créer son produit et des composants qui n'existent 
pas encore et tu n'as pas à te prendre la tête avec accepts_...
Posted by Arnaud Lec (moustach)
on 2009-06-29 11:51
Petit up pour mise à jour et re-problème
J'ai réussit a faire ce que je souhaitais avec le tuto 
http://media.pragprog.com/titles/fr_arr/multiple_models_one_form.pdf

Ça fonctionne parfaitement pour l'édition d'un produit dans mon cas. Par 
contre pour l'ajout d'un nouveau produit, j'obtiens 2 erreurs:
- La première car il veut créer les components avant d'avoir créer le 
produit et qu'il faut absolument un product_id pour faire l'association
- La seconde car apparemment il existerait un enregistrement vide 
invisible (etrange)

Pour la seconde erreur je reçoit effectivement dans le error_messages 
une ligne pour chaque component que j'ai voulu associer + 1 ligne peut 
importe le nombre de component
Dans le cas d'une édition, le produit existant déjà, le product_id 
fonctionne déjà.

Y-a-t-il un moyen de connaitre à l'avance le prochain id d'une 
table/modèle afin de le mettre en paramètre pour la création d'un 
component ou non ? (je verrais ensuite pour la correction du problème de 
l'entrée vide)

Merci d'avance
Posted by Arnaud Lec (moustach)
on 2009-06-29 12:08
bon j'ai fait un truc débile et ca a marché.
J'ai fait un hidden field qui dans le cas d'un edit recoit le product_id 
du produit en cours et dans le cas d'un new recoit 0 par défaut.
Une fois le formulaire soumis, le product_id du component est changé je 
ne sais trop comment par le product_id du produit nouvellement créé.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.