1

In my app there are products and images, which I manage via a simple admin panel. I can successfully add images to products if there are no images, but when I upload at least one (I can do it via edit or initial create), I can't do further uploads or delete existing images. I simply don't understand why the initial create or update works, but the further don't, if there is a mistake with my routes or in my controller, it would've been there at the first picture addition, wouldn't it?

This is the mistake when I try to add a new picture to an existing product with existing pictures via editing (if there are no initial pictures the update performs correctly) :

ActionController::RoutingError (No route matches [POST] "/admin/products/20"):
  actionpack (4.2.4) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  web-console (2.2.1) lib/web_console/middleware.rb:39:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'

My form:

=form_for([:admin, @product]) do |f|
                %p
                    ...a lot of simple fields, that are working correctly
                    .box
                        %h3 Options
                        =f.fields_for :options do |builder|
                            =render 'option_fields', f: builder
                            %br
                        =link_to_add_fields 'Add an option', f, :options

                    =f.fields_for :image, Image.new, html: { multipart: true, id: "fileupload"  } do |op|
                        = op.label 'Load product pictures'
                        = op.file_field :image, multiple: true, id: 'fileupload', name: "product[images_attributes][][image]", class: 'form-control'
                    -if @product.images.any?
                        .box
                            %h6 Delete existing pictures
                            %p
                                =f.fields_for :images do |builder|
                                    =image_tag builder.object.image, width: 120
                                    =builder.label :_destroy, 'Delete picture'
                                    =builder.check_box :_destroy
                                    %br
                                    %hr.short.alt
                =f.submit 'Save', id: 'submit-data', class: 'btn btn-success'
                =link_to 'Back', admin_path, class: 'btn btn-info'

This is my Products-Admin-controller

class Admin::ProductsController < AdminController

    before_action   :find_product, only: [:edit, :destroy, :update]

    def index
        @products = Product.all
    end

    def edit
    end

    def new
        @product = Product.new
        option = @product.options.build
        @product.servizations.build
    end

    def create
        @product = Product.new(product_params)
        if @product.save
            redirect_to admin_products_path
            flash[:success] = "Created"
        else
            render action: :new
        end
    end

    def update
        if @product.update!(product_params)
            redirect_to edit_admin_product_path(@product)
            flash[:success] = "Updated"
        else
            render action: :edit
        end
    end

    def destroy
        if @product.destroy
            redirect_to admin_products_path
            flash[:info] = 'Deleted
        end
    end

    private

        def product_params
            params.require(:product).permit(:title, :description, :advertising_text,
                :fancy_quote, :hot, :hotpic, :product_size_ids, :material,
                { volume_ids: [] }, { color_ids: [] }, { addservice_ids: [] }, :category_id, :subcategory_id, 
                options_attributes: [:size, :weight, :price, :material, :product_id, :id],
                images_attributes: [ :image, :product_id, :id ],
                servizations_attributes: [:id, :product_id, :addservice_id, :coefficient]
                )
        end

        def find_product
            @product = Product.find(params[:id])
        end
end

My product model:

class Product < ActiveRecord::Base

    validates :title, :description, :advertising_text, presence: true
    validates :category_id, :subcategory_id, presence: true

    mount_uploader :hotpic, HotpicUploader

    belongs_to  :category 
    belongs_to  :subcategory
    has_many    :options
    has_many    :images, dependent: :destroy
    has_many    :hot_pics
    has_many    :line_items

    has_many    :voluminazations
    has_many    :volumes, through: :voluminazations

    has_many    :colorizations
    has_many    :colors, through: :colorizations

    has_many    :accompanships
    has_many    :accompanies, through: :accompanships

    has_many    :servizations
    has_many    :addservices, through: :servizations

    accepts_nested_attributes_for :options
    accepts_nested_attributes_for :images
    accepts_nested_attributes_for :hot_pics
    accepts_nested_attributes_for :servizations

    before_destroy  :ensure_not_referenced_by_any_line_item

    def initialized_servizations # this is the key method
    [].tap do |o|
      Addservice.all.each do |addservice|
        if c = servizations.find { |c| c.addservice_id == addservice.id }
          o << c.tap { |c| c.enable ||= true }
        else
          o << Servization.new(addservice_id: addservice.id)
        end
      end
    end
end

    private

        # Ensure there are no line items referencing this product
        def ensure_not_referenced_by_any_line_item
            if line_items.empty?
                return true
            else
                errors.add(:base, 'Line Items present')
                return false
            end
        end

end

My routes if they matter:

resources :products do
    resources :servizations
    resources :colors
    resources :options do
      resources :option_pics
    end
  end

  namespace :admin do
    get '', to: 'dashboard#index', as: '/'
    resources :products do
      resources :images
    end
    resources :categories
    resources :subcategories
    resources :volumes
    resources :members
    resources :addservices
    resources :settings
    resources :deliveries
  end

Update. As requested, my rake routes:

admin_product_images GET    /admin/products/:product_id/images(.:format)                            admin/images#index
                               POST   /admin/products/:product_id/images(.:format)                            admin/images#create
       new_admin_product_image GET    /admin/products/:product_id/images/new(.:format)                        admin/images#new
      edit_admin_product_image GET    /admin/products/:product_id/images/:id/edit(.:format)                   admin/images#edit
           admin_product_image GET    /admin/products/:product_id/images/:id(.:format)                        admin/images#show
                               PATCH  /admin/products/:product_id/images/:id(.:format)                        admin/images#update
                               PUT    /admin/products/:product_id/images/:id(.:format)                        admin/images#update
                               DELETE /admin/products/:product_id/images/:id(.:format)                        admin/images#destroy
                admin_products GET    /admin/products(.:format)                                               admin/products#index
                               POST   /admin/products(.:format)                                               admin/products#create
             new_admin_product GET    /admin/products/new(.:format)                                           admin/products#new
            edit_admin_product GET    /admin/products/:id/edit(.:format)                                      admin/products#edit
                 admin_product GET    /admin/products/:id(.:format)                                           admin/products#show
                               PATCH  /admin/products/:id(.:format)                                           admin/products#update
                               PUT    /admin/products/:id(.:format)                                           admin/products#update
                               DELETE /admin/products/:id(.:format)                                           admin/products#destroy
mohnstrudel
  • 639
  • 8
  • 22
  • I can't see anything wrong with it. The error your getting means that your are using `POST` with that path. It should be a `PATCH`/`PUT`. Can you post both your edit and new views please. – DickieBoy Sep 28 '15 at 12:04
  • I'm afraid they are pretty simple: `%h1 Editing: =@product.title =render 'form'` and new: `%h1 Create new product =render 'form'` – mohnstrudel Sep 28 '15 at 12:15
  • What version of rails are you using? Can i see the relevant `rake routes` – DickieBoy Sep 28 '15 at 12:33
  • My rails version: `rails -v Rails 4.2.4` Rake routes I will post as update to the initial question, they take too much space. – mohnstrudel Sep 28 '15 at 12:56
  • Why do you have nested routes for images, but also allow them to be created from within the form? – DickieBoy Sep 28 '15 at 13:33
  • Could you inspect the element of the form and see what it has. Specifically the action its mapped to? It should be a data link for patch/put? – Andy Sep 28 '15 at 13:41
  • @Andy This is my form element inspected: `
    ` @DickieBoy The nesting was added just recently, to test some things out, it doesn't work in both cases.
    – mohnstrudel Sep 28 '15 at 14:06
  • Ok, so just looked it up. Is there a hidden input with the name `_method` in the form as well? And if so, what does it say when in edit? – Andy Sep 28 '15 at 14:11
  • Indeed, there is. While editing it says: `` This is the complete html after
    and before fields start: ` `
    – mohnstrudel Sep 28 '15 at 14:18
  • For the record, I have another similar project, and after reading this - http://stackoverflow.com/questions/15599613/multiple-image-uploads-in-a-nested-form-with-carrierwave I tried this solution - https://u.osu.edu/hasnan.1/2014/03/30/rails-4-multiple-file-upload-with-carrierwave-nested-form-and-jquery-file-upload/ Which works just fine. The basic idea is to move handling images to their own controller and don't use nested attributes. I'll post an update if this work with the project I initially posted. – mohnstrudel Sep 28 '15 at 16:16

0 Answers0