Недопустимые параметры для вложенных ассоциаций «многие-ко-многим» в Rails 7

У меня есть 4 модели: Бизнес, Магазин, Продукт и МагазинПродукт.

У бизнеса много магазинов и продуктов

Я хочу, чтобы в магазине было много товаров, а товары должны принадлежать многим магазинам. При выборе продуктов, принадлежащих магазину, я также хочу указать количество каждого продукта. Это должно быть сделано с помощью вложенных форм в формах нового и редактирования магазина, и я использую компонент вложенной формы стимула.

Я получаю недопустимые параметры при сохранении формы магазина.

ошибка

Unpermitted parameters: :Product_ids, :quantity, :_destroy. Context: { controller:
StoresController, action: update, request: #<ActionDispatch::Request:0x00007f5cc927cfe0>, 
params: {"_method"=>"patch", "authenticity_token"=>"[FILTERED]", "store"=>{"name"=>"Arikeade Trendings, Challenge", 
"Product_ids"=>"6", "quantity"=>"10", "_destroy"=>"false"}, 
"button"=>"", "controller"=>"stores", "action"=>"update", "business_id"=>"3", "id"=>"2"} }

магазин.рб

  # validates presence, uniqueness, length and case-sensitivity of name attribute
  validates :name, presence: true, uniqueness: {scope: :business_id, message: "Store  name must be unique"}, length: { minimum: 3, maximum: 255 }

  belongs_to :user
  belongs_to :business

  # store products association
  has_many :store_products, inverse_of: :store, dependent: :destroy
  has_many :products, through: :store_products, dependent: :destroy

  # accepted nested form attributes
  accepts_nested_attributes_for :store_products, reject_if: :all_blank, allow_destroy: true
end

store_product.rb

class StoreProduct < ApplicationRecord
  validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
  belongs_to :product
  belongs_to :store
end

продукт.рб

class Product < ApplicationRecord
  ...

  belongs_to :user
  belongs_to :business

  # store products association
  has_many :store_products, dependent: :destroy
  has_many :stores, through: :store_products
  
  '''

end

store_controller.rb

class StoresController < ApplicationController
    
    ...

    def new
        @store = Store.new
    end

    def create
        @store = @business.stores.build(store_params)
        @store.user = current_user
        if @store.save
            respond_to do |format|
                format.html { redirect_to business_store_path(@business, @store), notice: 'store successfully created' }
            end
        else
            render :new, status: :unprocessable_entity
        end
    end

    def edit
        
    end

    def update
        if @store .update(store_params)
            respond_to do |format|
                format.html { redirect_to business_store_url(@business, @store), notice: 'store successfully updated' }
            end
        else
            render :edit, status: :unprocessable_entity
        end
    end

    private

    def store_params
        params.require(:store).permit(:name, product_ids: [], store_products_attributes: [:id, :_destroy, :quantity, :product_id])
    end

    def find_store
      @store ||= Store.find(params[:id])
    end

    def find_business
        @business ||= Business.find(params[:business_id])
    end

    def find_products
        @business = Business.find(params[:business_id])
        @products ||= @business.products.pluck(:name, :id)
    end

    ...

end

магазины/форма

<div data-controller='nested-form'>
    <%= form_with model: [business, store] do |f| %>
        <%= render 'shared/error_messages', f: f %>

        <div class = "mb-3">
            <%= f.text_field :name, placeholder: 'Store name', class: 'form-control' %>
        </div>

        <!--<div data-controller = "tom-select">
            <small>Add products to store</small>
            <%#= f.select :product_ids, @products, {}, { multiple: true, id: "select-products", class: 'mb-3 form-control' } %>
        </div>-->

        <div class = "d-block w-100 mt-3">
            <h6><small>Add store products:</small></h6>
            <hr>
        </div>

        <%# Custom logic for nested form %>
        <template data-nested-form-target = "template">
            <div class = "nested-form-wrapper row w-100" data-new-record = "<%= f.object.new_record? %>">
                <div class = "col-md-4" data-controller = "tom-select">
                    <%= f.select :Product_id, @products, { include_blank: "Select Product" }, class: "form-control mb-3 form-control" %>
                </div>

                <div class = "col-md-4">
                    <%= f.number_field :quantity, placeholder: 'Quantity', class: "form-control" %>
                </div>

                <div class = "col-md-3">
                    <button type = "button" class = "btn btn-danger btn-sm border" style = "font-size: 10px;" data-action = "nested-form#remove">Remove product</button>
                </div>


                <%= f.hidden_field :_destroy %>
            </div>
        </template>

        <!-- Inserted elements will be injected before that target. -->
        <div data-nested-form-target = "target"></div>

        <button type = "button" class = "btn btn-success w-100 mb-3" style = "font-size: 10px;" data-action = "nested-form#add">Add Product</button>

        <div class = "submit">
            <%= link_to business_stores_path(@business), class: "btn btn-light rounded-1 border me-2" do %>
                <%= image_tag "x.png", width: "19" %>
            <% end %>

            <%= button_tag type: 'Submit', class: "btn btn-success rounded-1 border" do %>
                <%= image_tag "check.png", width: "19" %>
            <% end %>
        </div>
    <% end %>
</div>
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Несколько вещей:

  1. ваша форма создает параметры "Product_ids", но вы разрешаете :product_ids в своем методе store_params в контроллере (заглавная буква P — это ошибка).

  2. ваш :store_product_attributes в методе store_params ожидает возврата хеша значений, например:

    'store_product_attributes'=>{'quantity'=>'10', '_delete'=>'false'}

Вам нужно посмотреть сгенерированный HTML в вашей форме. Он должен создавать имена полей формы, такие как store_product_attributes[quantity] и store_product_attributes[_delete].

Один из способов - это что-то вроде:

f.fields_for :product_attributes do |prod_attr|
  ...
  <%= prod_attr.number_field :quantity, placeholder: 'Quantity', class: "form-control" %>

  ...

  <%= prod_attr.hidden_field :_destroy %>

  ...
end

Я не в курсе стимулов, поэтому не знаю, как это на это повлияет. Но это стандартный код для получения вложенных атрибутов в параметрах формы.

Я только что понял это и ответил на свой вопрос. Спасибо большое, что указали на мои ошибки. Мой подход был совершенно неправильным.

Tolase Adegbite 26.02.2024 21:33

Другие вопросы по теме