2016-10-27 3 views
1

Voilà comment mon schéma ressemble à:Quelle est la bonne façon d'ajouter les options de produits que l'utilisateur a sélectionné pour le panier?

Combo  | Product  | Variant  | OptionType | OptionValue 
    id  |  id  |  id, name  |  id   |  id 
    name  |  name  |  price  |  name  |  name 
    dicount |  combo_id |  product_id |  variant_id |  option_type_id 
          |  price  |     |  price 
________________________________________________________________________________________ 

       Cart  | CartItem 
        id  |  id 
        user_id |  cart_id 
          |  purchasable_id 
          |  purchasable_type 
          |  quantity 

       //purchasble: polymorphic, Combo and Product are purchasable 

Un exemple serait beaucoup plus facile à comprendre

Product: Some Shirt, Some Pants, SomeOther Shirt, etc., 
Combo: Shirt + Pants combo (discount: $20) 

For the product 'Some Shirt', 
Variants: Small ($30), Medium ($35), Large ($40) 
OptionTypes: Print, Add-ons 
OptionValues for 'Print': CustomLogo ($10), FullSizePrint ($20) 
OptionValues for 'Add-ons': Frills ($1), InnerPockets ($2) 

Quand j'ajouter quelque chose au panier, un Cart est créé et nouveau CartItem est créé pour un nouveau Cart vient de créer. Et ma question est

Comment puis-je obtenir la variante et les options utilisateur a sélectionné?

* Note: Je ne wan't pas envoyer un tableau de optionValueId s et variantId en JSON et calculer et copie prix à CartItem: J'ai vraiment besoin de ces optionValueId s et variantId s persister à savoir, en db.

En ce moment, CartItem ne contient que le id des Product et évidemment Product.Variants donneraient toutes les variantes possibles, même pour OptionTypes et OptionValues

Je regardais peu profondément comment Spree fait cela: CartItem a variant_id au lieu de product_id . En d'autres termes, ils ajoutent Variants au panier et obtiennent l'objet produit :via variant. Eh bien, ils éliminent la nécessité d'envoyer séparément variantId mais je ne sais toujours pas comment ils obtiennent et où ils stockent un tableau de optionValueId s l'utilisateur a sélectionné. J'ai également regardé ce SO Post mais il n'a aucune réponse et d'ailleurs il était plus spécifique à Spree.

À quoi j'ai pensé?

  • Ajouter une autre colonne options_chosen dans CartItem et envoyer dans un tableau sérialisée de l'utilisateur de optionValueId a choisi; Pourquoi ça pourrait être mauvais? Tout d'abord, cela ne fonctionne pas pour Combo. Deuxièmement, Atomicity est perdue.
  • Ajouter une colonne options_chosen dans un nouveau modèle appelé CartVariant référencement Variant et ajouter CartVariant s le chemin de la Spree au panier. Mes pensées: Je ne sais pas si c'est le bonne façon de le faire. Obtenir l'objet de produit devrait être comme CartItem.CartVariant.Variant.Product et je ne sais pas comment faire ce travail pour Combo s. Btw, même ici l'atomicité est perdue;
+0

Salut Zeke, je me bats avec cette question précise en ce moment. Avez-vous compris? J'ai une page de produit avec deux variantes disponibles pour un client à choisir. J'ai pensé à quelques façons de le faire, mais ils se sentent tous comme un hack. – Mark

Répondre

0

J'ai inclus le product_id en tant que champ masqué sur la page du produit, puis j'ai créé des boutons d'entrée radio pour choisir une variante spécifique. Lorsque j'ai soumis le formulaire, je passe les paramètres product_id et variant_id au contrôleur LineItems, où je les utilise pour construire mon line_item. Cela a-t-il du sens? J'ai travaillé dessus pendant des heures, et ça marche finalement!

<%= form_tag line_items_path, method: :post, :id => "print_form" do %> 
    <%= hidden_field_tag :product_id, @product.id %> 

    <% @product.variants.each do |variant| %> 
    <label> 
     <input type="radio" name="variant_id" value="<%= variant.id %>" /><%= variant.name %> 
    </label> 
    <% end %> 
+0

Il n'y a absolument aucun problème à trouver quelle variante l'utilisateur a ajouté à 'cart', car je n'ajoute pas' products', mais 'variants' au panier _ (je peux identifier le produit en utilisant' variant.product') _ comme _Spree_ fait. De cette façon, je n'ai même pas besoin d'envoyer le 'product_id's au serveur. –

+0

Le vrai problème réside dans l'envoi de 'OptionTypes' et' OptionValues'. Qui plus est, ils sont imbriqués sous 'Variant's quand il s'agit de' Combo's, nous empêchant ainsi de lier directement ceux-ci à 'CartItem' ou' LineItem' –

+0

Right, mais pourquoi n'ajoutez-vous pas aussi les OptionTypes et OptionValues? , de la même manière que j'envoie les sélections Variant avec le produit? Il devient juste plusieurs articles de ligne connexes dans mon panier. – Mark