2016-11-07 1 views
0

Ich mache einen E-Commerce. Ich habe Produkte, die viele Produktoptionen haben und gleichzeitig nur eine Variante haben. Ich versuche, dass die Ansicht, um das Produkt zu erstellen, die Option hat, einen Block hinzuzufügen, wo die Felder des Modells und die Änderungen der Variante angezeigt werden, die ihm zugeordnet ist. Das Problem ist, dass, wenn ich gehe, um ein Produkt mit Varianten zu bearbeiten, und löschen Sie ein oder zwei oder den gewünschten Betrag, nicht gelöscht.Verschachtelte Attribute können nicht gelöscht werden. Ruby on rails

Produkt Controller

class ProductsController < ApplicationController 
    before_action :set_product, only: [:show, :edit, :update, :destroy] 
    before_action :authenticate_admin_user!, only: [:new, :create, :edit, :update, :destroy] 

    # GET /products 
    # GET /products.json 
    def index 
    if admin_user_signed_in? 
     @authenticate = true 
    else 
     @authenticate = false 
    end 

    @products = Product.order(:index) # si vamos a todos los productos sin buscar nada 

    if params[:search] # si hay parametro de busqueda 
     @products = Product.where("name LIKE ?", "%#{params[:search]}%") # buscamos todos los productos que tengan el mismo nombre 
     if @products.length < 1 # si no hay al menos uno devolvemos todos los productos 
     @products = Product.all 
     end 
    end 
    end 

    # GET /products/1 
    # GET /products/1.json 
    def show 
    if admin_user_signed_in? 
     @authenticate = true 
    else 
     @authenticate = false 
    end 
    end 

    # GET /products/new 
    def new 
    @product = Product.new 
    end 

    # GET /products/1/edit 
    def edit 
    end 

    # POST /products 
    # POST /products.json 
    def create 
    @product = Product.new(product_params) 

    respond_to do |format| 
     if @product.save 
     format.html { redirect_to @product} 
     format.json { render :show, status: :created, location: @product } 
     else 
     format.html { render :new } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PATCH/PUT /products/1 
    # PATCH/PUT /products/1.json 
    def update 
    products = Product.order(:index) 
    indexOld = Product.where(:name => @product['name'])[0]['index'].to_i 
    indexNew = product_params['index'].to_i # el producto que se va a actualizar 
    if indexOld != indexNew 
     for i in (indexNew - 1..indexOld - 1) # el indice nuevo simpre va a ser menor que el indice viejo 
     puts 'salida:' 
     puts Product.find(products[i].id).update(:index => (products[i]['index'].to_i + 1).to_s) # aumento en uno el indice del primer elemento a mover 
     end 
    end 
    respond_to do |format| 
     if @product.update(product_params) 
     format.html { redirect_to @product} 
     format.json { render :show, status: :ok, location: @product } 
     else 
     format.html { render :edit } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /products/1 
    # DELETE /products/1.json 
    def destroy 
    index = @product.index 
    products = Product.order(:index) 
    products.each do |p| 
     if p.index > index 
     p.update(:index => p.index - 1) 
     p.save 
     end 
    end 
    DetailOrder.where(:product_id => @product.id).each do |detail| 
     detail.destroy 
     Order.find(detail.order_id).destroy 
    end 
    @product.destroy 
    respond_to do |format| 
     format.html { redirect_to products_url } 
     format.json { head :no_content } 
    end 
    end 

Form von Produkt

= form_for @product, html: { multipart: true } do |f| 
    .row 
    .form-group.col-lg-6 
     .field 
     = f.file_field :image1 
    .row 
    .form-group.col-lg-6 
     .field 
     = f.file_field :image2 
    -if action_name == 'new' 
    - if Product.order(:index).length > 0 
     - index = Product.order(:index).last['index'] 
     = f.number_field :index, value: index + 1,:class => 'disp-none' 
    - else 
     = f.number_field :index, value: 1,:class => 'disp-none' 
    -else 
    .row 
     .form-group.col-lg-6 
     .field 
      = f.number_field :index, :placeholder => 'Indice', value: @product.index, max: Product.order(:index).last['index'],:class => 'form-control input-border-left' 
    .row 
    .form-group.col-lg-6 
     .field 
     = f.number_field :stock, :placeholder => 'Stock', :class => 'form-control input-border-left' 
    .row 
    .form-group.col-lg-6 
     .field 
     = f.text_field :name, :placeholder => 'Nombre', :class => 'form-control input-border-left' 

    .row 
    .form-group.col-lg-6 
     .field 
     = f.text_area :description, :placeholder => 'Descripcion', :class => 'form-control input-border-left' 

    .row 
    .form-group.col-lg-6 
     .field 
     = f.number_field :price, :placeholder => 'Precio a mostrar', :class => 'form-control input-border-left' 

    .row 
    .form-group.col-lg-6 
     .field 
     = f.label :Estado 
     %br/ 
     = f.select :state, options_for_select(['Disponible', 'No disponible']), {}, {class: 'form-control input-border-left'} 
    .row 
    .form-group.col-lg-6 
     .field 
     = f.label :Envio 
     %br/ 
     = f.check_box :shippingInside 

    .row 
    .form-group.col-lg-6 
     .field 
     = f.text_field :priceComparison, :placeholder => 'Precio anterior', :class => 'form-control input-border-left' 

    .row 
    .form-group.col-lg-6 
     .field 
     = f.label :vendor_id 
     %br/ 
     = f.select :vendor_id, Vendor.all.collect { |vendor| [vendor.name, vendor.id] }, {}, {class: 'form-control input-border-left'} 

    .row 
    .form-group.col-lg-6 
     .field 
     = f.label :category_id 
     %br/ 
     = f.select :category_id, Category.all.collect { |category| [category.name, category.id] }, {}, {class: 'form-control input-border-left'} 
    .row 
    .form-group.col-lg-6 
     .field 
     = f.label :Oferta 
     %br/ 
     = f.check_box :offer 
    .row 
    .form-group.col-lg-6 
     .field 
     = f.text_field :nameVariants, :placeholder => 'Nombre para variantes', :class => 'form-control input-border-left' 
    .row 
    = f.fields_for :options_products do |op| 
     = render 'options_product_field', f: op 
    = link_to_add_association 'Agregar variante', f, :options_products 
    %br/ 
    .actions 
    = f.submit "Enviar", :class => 'button btn btn-primary bold' 

Produktmodell

class Product < ActiveRecord::Base 
    #relations 
    belongs_to :category 
    belongs_to :vendor 
    has_many :options_products, :dependent => :destroy 

    #accepts 
    accepts_nested_attributes_for :options_products, allow_destroy: true 

    #validations 
    validates :name, presence:true 
    validates :name, uniqueness:true 
    validates :state, presence:true 
    validates :category_id, presence:true 
    validates :vendor_id, presence:true 

    has_attached_file :image1, 
        styles: {large: "600x4600>", medium: "300x300>", thumb: "150x150#" } 
    validates_attachment_content_type :image1, 
            content_type: /\Aimage\/.*\z/ 

    has_attached_file :image2, 
        styles: {large: "600x4600>", medium: "300x300>", thumb: "150x150#" } 
    validates_attachment_content_type :image2, 
            content_type: /\Aimage\/.*\z/ 
end 

Option Produktmodell

class OptionsProduct < ActiveRecord::Base 
    belongs_to :product 
    has_one :variant, :dependent => :destroy 

    accepts_nested_attributes_for :variant, allow_destroy: true 
end 

Variante Modell

class Variant < ActiveRecord::Base 
    belongs_to :options_product 
    has_attached_file :image, 
        styles: {large: "600x4600>", medium: "300x300>", thumb: "150x150#" } 
    validates_attachment_content_type :image, 
            content_type: /\Aimage\/.*\z/ 
end 

Skript für Hinzufügen und Entfernen von Feldern

$(document).on 'ready page:load', -> 
    $('form').on 'click', '.remove_field', (event) -> 
    $(this).prev('input[type=hidden]').val('1') 
    $(this).closest('fieldset').hide() 
    event.preventDefault() 

    $('form').on 'click', '.add_field', (event) -> 
    time = new Date().getTime() 
    regular_expression = new RegExp($(this).data('id'), 'g') 
    $(this).before($(this).data('fields').replace(regular_expression, time)) 
    event.preventDefault() 
+0

Sie sollten nur die relevanten Abschnitte Ihres Codes reduzieren und veröffentlichen. –

Antwort

0

Eine andere mögliche Lösung wäre cocoon gem zu verwenden, die Sie verschachtelte Attribute für Ihr Produkt zu implementieren, um easiy erlauben würde. (Dies wird alle JS aus der Sicht für Sie nehmen, so dass Sie dies einfach implementieren können)