0

Je travaille actuellement sur une boutique en ligne et j'utilise Rails 5. Je les modèles et les relations suivantes:Rails 5: attribut de mise à jour en a beaucoup d'autres rejoignent dans le tableau

# Products 
class Product < ApplicationRecord 
    has_many :product_variants 
    has_many :variants, through: :product_variants 
    ... 

class Variant < ApplicationRecord 
    has_many :product_variants 
    has_many :products, through: :product_variants 
    ... 

# My join table between Product and Variant 
class ProductVariant < ApplicationRecord 
    belongs_to :price, optional: true 
    belongs_to :product, optional: true 
    belongs_to :variant, optional: true 

Mon modèle ProductVariant ont un attribut supplémentaire que je voudrais être modifiable, t.integer "quantity". Je suis un peu perdu quand il s'agit de mettre à jour cet attribut dans un form_for.

Ma solution actuelle pour la forme ressemble à ceci (j'utilise HAML):

= form_for @product, html: { method: :patch } do |product_builder| 

    = product_builder.fields_for :product_variants, product_variant do |variant_builder| 

    = variant_builder.hidden_field :variant_id, value: product_variant.variant.id 

    = variant_builder.number_field :quantity 

    = variant_builder.submit 

Mais il ne fonctionne pas correctement. Cela aurait été plus facile si la table de jointure avait une colonne ID, mais je suppose que c'est redondant dans la base de données. Il semble actuellement créer une autre instance d'un ProductVariant lorsque je clique sur le bouton Envoyer.

Une idée sur ce que je devrais mettre à jour correctement mon attribut quantity dans ma table de jointure?

Pour l'achèvement

C'est ce qui est connecté lorsque je clique soumettre:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"uisxjfvj9LxZVJWcDVos66tJWNfHkld5+/gdfGv1D2WZsrLJcH7KLxb5eSDAYIL23mEEho18Pv/53bSEP8cC9A==", "product"=>{"product_variants_attributes"=>{"0"=>{"variant_id"=>"1", "product_id"=>"11", "quantity"=>"20", "id"=>""}}}, "commit"=>"Update Product variant", "id"=>"11"} Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 11], ["LIMIT", 1]] Unpermitted parameter: :id (0.1ms) begin transaction Brand Load (0.2ms) SELECT "brands".* FROM "brands" WHERE "brands"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]] Variant Load (0.2ms) SELECT "variants".* FROM "variants" WHERE "variants"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] Brand Exists (0.2ms) SELECT 1 AS one FROM "brands" WHERE "brands"."name" = ? AND ("brands"."id" != ?) LIMIT ? [["name", "Fredric Malle"], ["id", 4], ["LIMIT", 1]] SQL (0.4ms) INSERT INTO "product_variants" ("variant_id", "product_id", "quantity") VALUES (?, ?, ?) [["variant_id", 1], ["product_id", 11], ["quantity", 20]] (2.7ms) commit transaction (0.2ms) SELECT COUNT(*) FROM "note_parts" INNER JOIN "product_note_parts" ON "note_parts"."id" = "product_note_parts"."note_part_id" WHERE "product_note_parts"."product_id" = ? [["product_id", 11]] Redirected to http://localhost:3000/products/11/edit Completed 302 Found in 15ms (ActiveRecord: 4.0ms)

+0

Vous recevez 'Paramètre non autorisé:: id', il y a un attribut' id' que vous envoyez qui n'est pas dans les paramètres forts. –

+0

Merci @ SebastiánPalma, oui, vu cela. Je n'ai pas vraiment envie d'envoyer un identifiant car c'est une table de jointure et la colonne id n'existe pas. Si j'ajoute 'id' à mes paramètres forts, j'obtiens l'erreur suivante:' NoMethodError (méthode non définie 'to_sym 'pour nil: NilClass):'. Donc je pense que j'ai de plus gros problèmes. :( – Anders

Répondre

1

Vous faites un has_many :though. Dans ce cas, la table de jointure doit avoir une clé primaire (généralement: id). Sinon, vous ne pouvez pas accéder directement à la table de jointure comme vous le souhaitez ici. D'un autre côté, si vous n'avez pas besoin d'un accès direct à la table de jointure (par exemple, aucune colonne supplémentaire), vous pouvez définir has_and_belongs_to_many, sans colonne id pour la table de jointure.

+0

Merci, j'ai ajouté une clé primaire pour la table et maintenant ça marche. – Anders