При обновлении происходит сбой проверки, форма продолжает создавать метод? - PullRequest
0 голосов
/ 10 июня 2019

Цель: обновить существующие записи модальным способом без необходимости ссылки_ на новую страницу.

Проблема: я предполагаю, что моя проблема в том, что я не могу идентифицировать точную запись на странице с формой, потому что я не могу знать это, пока форма не отправлена.

ShopProduct Controller:

  def new
    @shop_product = ShopProduct.new
  end

  def create
    @shop_product = ShopProduct.new(shop_product_params)
    @shop = Shop.find_by(params[:shop_id])
    product = Product.find_by(params[:product_id])
    @shop_product.product_id = product.id
    @shop_product.shop_id = @shop.id

      if @shop_product.save!
        redirect_to '/'
        flash[:notice] = "saved"
      else
        redirect_to '/'
        flash[:notice] = "no saved"
      end
  end

  def update
    @shop_product = ShopProduct.find_by(store_variant_id: params[:store_variant_id])

    respond_to do |format|
      if @shop_product.update_attributes!(product_id: params[:product_id], sync: params[:sync])

        format.html { redirect_to @shop_product, notice: 'Shop product was successfully updated.' }
        format.json { render :show, status: :ok, location: @shop_product }
      else
        format.html { render :edit }
        format.json { render json: @shop_product.errors, status: :unprocessable_entity }
      end
    end
  end

Помимо ссылок на новую страницу, я могу думать только об определении непосредственно на

Я загружаю форму из этого ShopDashboardController:

  def product_variants
    @shop = Shop.find(params[:shop_id])
    session = ShopifyAPI::Session.new(domain: @shop.shopify_domain, token: @shop.shopify_token, api_version: '2019-04')
    ShopifyAPI::Base.activate_session(session)
    @in_store_products = ShopifyAPI::Product.find(:all)
    @in_store_product = ShopifyAPI::Product.find(params[:shopify_product_id])
    @in_store_variants = ShopifyAPI::Variant.find(:all, params: { product_id: params[:shopify_product_id]})
    @shop_products = ShopProduct.where(shop_id: @shop)
    @products = Product.all
    @shop_product = ShopProduct.find_or_create_by(store_variant_id: params[:store_variant_id])
  end

Теперь, как упоминалось выше, единственной уникальной записью для любого ShopProduct является идентификатор и store_variant_id ... Если я использую find_by в def product_variants, страница не будет загружаться из-за невозможности идентифицировать @shop_product. Я не могу передать эти параметры, потому что может быть несколько store_variant_ids, поэтому я передаю только Shop.id и ShopProduct.store_product_id. Но store_product_id не является уникальным идентификатором, так как несколько записей могут иметь один и тот же. Единственными уникальными записями являются id и store_variant_id.

Форма (variant из цикла do):

<% @in_store_variants.each do |variant| %>
    ...
    <%= form_for @shop_product do |f| %>
      <%= f.collection_select :product_id, @products, :id, :sku %>
      <%= f.hidden_field :store_product_id, value: variant.product_id %>
      <%= f.hidden_field :store_variant_id, value: variant.id %>
      <%= f.hidden_field :shop_id, value: @shop.id %>
      <%= f.hidden_field :sync, value: true %>
      <%= f.submit "Sync" %>
    ...
<% end %>

Я могу создавать только новые записи.

Когда я снова использую форму для обновления, я получаю:

ActiveRecord::RecordInvalid (Validation failed: Store variant has already been taken):
app/controllers/shop_products_controller.rb:61:in `create'

Модель ShopProduct:

  belongs_to :product
  has_one :shop
  has_one :order
  validates :store_variant_id, uniqueness: true, on: :create

Если запись существует, не должна ли она обновляться? Или я что-то здесь упускаю?

Можно преследовать мою цель только с помощью rails / ruby ​​или необходим javascript?

UPDATE:

Я попытался определить ShopProduct на внешнем интерфейсе так:

<% @in_store_variants.each do |variant| %>
    <% shop_product = @shop_products.find_by(store_variant_id: variant.id)  %>
<%= form_for shop_product do |f| %>
  <%= f.collection_select :product_id, @products, :id, :sku %>
  <%= f.hidden_field :store_product_id, value: variant.product_id %>
  <%= f.hidden_field :store_variant_id, value: variant.id %>
  <%= f.hidden_field :shop_id, value: @shop.id %>
  <%= f.hidden_field :sync, value: true %>
  <%= f.submit "Sync" %>
<% end %>

При отправке:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"gaMboYCSE8v63TVzmgx4pZDMhoz205f1MV+VMhmFA/WWhVh5Pcu6u/qayU8lDmjeRXw==", "shop_product"=>{"product_id"=>"1", "store_product_id"=>"1965345", "store_variant_id"=>"19364273", "shop_id"=>"1", "sync"=>"true"}, "commit"=>"Sync", "id"=>"12"}

Ошибка:

NoMethodError (undefined method `update' for nil:NilClass):

или с атрибутами обновления:

NoMethodError (undefined method `update_attributes!' for nil:NilClass):

Если он его находит, разве он не должен работать? Парам передается

1 Ответ

0 голосов
/ 10 июня 2019

Это потому, что эта форма обслуживает только действие create.Обычно, если вам нужно обновить resource, вы переходите на /shop_products/:id/edit.

Но если вы действительно хотите повторно использовать эту форму, добавление дополнительных условий немного сложнее, но вам нужноотправьте запрос PUT на /shop_products/:id, и он вызовет действие #update вашего контроллера.Форма по умолчанию отправляет запрос POST, так что учтите это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...