创建将使用表单对象创建2个模型的动态表单

时间:2015-12-08 09:55:43

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4

您好我有3个型号Product,Category和ProductSize。

在我的产品新视图中,用户应该能够选择产品的类别(T恤),然后该类别的尺寸列表(XS,S,M,L,XL)将下拉到用户可以输入他们拥有的每种尺寸的数量。然后他们填写其余字段并单击“创建”。

问题是,当用户点击创建传递给我的ProductsController Create操作的参数时,不包含size_id或数量。如何让视图传递正确的参数,其中包含每个quantity的{​​{1}}?

我创建Product和ProductSize的方式是通过表单对象。如果我可以获得创建动作的正确参数,我将能够完成剩下的工作。我只是无法弄清楚如何获得params中每个size_id的数量,这样我就可以创建Product和ProductSize。

我认为我的ProductController新操作和我的表单有问题。我从来没有创造过这样的形式,所以对我来说它是新的。

请查看product_size

的位置
size_id

这是我的表格

   35: def create
 => 36:   binding.pry
    37:   @product_form = ProductForm.new(product_params)
    38:   if @product_form.save
    39:     redirect_to @product
    40:     flash[:success] = "You have created a new product"
    41:   else
    42:     flash[:danger] = "Your product didn't save"
    43:     render "new"
    44:   end
    45: end

[1] pry(#<ProductsController>)> params
=> {"utf8"=>"✓",
 "authenticity_token"=>"QrORHJ5DsdidyoUDgMcCDO26/Uk9Uuq8N40FEqv240PYfZUKBh9Nirt25kimEorQ4luXqNKxKXoG4zqqGiLtdA==",
 "product"=>
  {"image"=>
    #<ActionDispatch::Http::UploadedFile:0x007fdaccb89120
     @content_type="image/jpeg",
     @headers="Content-Disposition: form-data; name=\"product[image]\"; filename=\"David-Marvier-Beauty-Fashion-Photography17.jpg\"\r\nContent-Type: image/jpeg\r\n",
     @original_filename="David-Marvier-Beauty-Fashion-Photography17.jpg",
     @tempfile=#<File:/var/folders/yx/znmx6qfj0c507bvkym6lvhxh0000gn/T/RackMultipart20151208-24784-1tgqy4v.jpg>>,
   "category_id"=>"3",
   "title"=>"Test",
   "price"=>"12",
   "description"=>"test",
   "tag_list"=>"test"},
 "product_size"=>{"quantity"=>""},
 "commit"=>"Create new product",
 "controller"=>"products",
 "action"=>"create"}

这是我的产品控制器。

<%= javascript_include_tag "custom" %>
<div class="container">
  <div class=“row”>
    <div class="col-md-6 col-md-offset-3">
      <div class="panel panel-primary">
        <div class="panel-body">
          <%= simple_form_for @product_form, html: { multipart: true }, method: :post do |f| %>
            <%= f.input :image, label:"Choose Image" %>
            <%= f.collection_select :category_id, @categories, :id, :name, include_blank: true, :prompt => "Select One Category" %>
            <% @categories.each do |category| %>
              <div class='sizes_container' id ='sizes_container_for_<%= category.id %>'>
                <% category.sizes.each do |size| %>
                  <%= size.title %>
                  <%= simple_fields_for @product_size do |f| %>
                    <%= f.input :quantity %>
                  <% end %>
                <% end %>
              </div>
            <% end %>
            <%= f.input :title, label:"Title"%>
            <%= f.input :price, label:"Price"%>
            <%= f.input :description,label:"Description" %>
            <%= f.input :tag_list,label:"Tags - Seperate tags using comma ','. 5 tags allowed per product" %>
            <%= f.button :submit, "Create new product", class: "btn-lg btn-success" %>
          <% end %>
        </div>
      </div>
    </div>
  </div>
</div>

Product.rb

class ProductsController < ApplicationController

  def new
    @product_form = Product.new
    @categories = Category.preload(:sizes).order(:name)
    @product_size = ProductSize.new
  end

  def create
    @product_form = ProductForm.new(product_params)
    if @product_form.save
      redirect_to @product
      flash[:success] = "You have created a new product"
    else
      flash[:danger] = "Your product didn't save"
      render "new"
    end
  end

  private

  def product_params
    params.require(:product).permit(
      :title,
      :price,
      :description,
      :tag_list,
      :category_id,
      :size,
      :quantity
    )
  end
end

ProductSize.rb

class Product < ActiveRecord::Base
  acts_as_taggable

    belongs_to :user
    belongs_to :category

  has_many :product_sizes

    validates :title, presence: true, length: { maximum: 30 }
    validates :description, presence: true, length: { maximum: 2000 }
    validates :category, :user_id, :price, presence: true

    has_attached_file :image, styles: { large: "600x600", medium: "250x250", thumb:"100x100#"}
    validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end

1 个答案:

答案 0 :(得分:0)

我认为您需要对产品型号进行少量更改,以便在参数中获得产品尺寸值

在产品型号中添加

accept_nested_attributes_for :product_sizes

在ProductController中添加

product_sizes_attributes:[:quntity]

删除一些你真正不需要它们的params。 size, quantity

产品参数应该如下所示

def product_params
    params.require(:product).permit(
      :title,
      :price,
      :description,
      :tag_list,
      :category_id,
      product_sizes_attributes: [:id, :size_id, :quantity]
    )
  end

您需要一些ajax实现来显示与类别相关的产品大小。 这样,您无法根据所选类别加载大小。

更改类别时发送ajax请求以呈现product_sizes部分。

部分应该看起来像这样

<%= f.simple_fields_for :product_sizes do |psf| %>
                    <%= psf.input :quantity %>
                  <% end %>
                <% end %>