使用嵌套表单初始化Object无效

时间:2016-06-29 20:16:35

标签: javascript ruby-on-rails activerecord nested-forms

我有一个品牌的模型,可以有许多产品,可以有很多类别。我有一个嵌套的表单来创建允许嵌套属性创建类别的产品。但我可以让它发挥作用。

class Brand < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_many :products, dependent: :destroy

  validates :name,  presence: true,
                    length: { maximum: 50 }
end

class Product < ActiveRecord::Base
  belongs_to :brand
  has_many :categories, dependent: :destroy
  accepts_nested_attributes_for :categories

  default_scope -> { order(created_at: :desc) }

  validates :brand_id, presence: true
  validates :name,     presence: true,
                       length: { maximum: 50 }
  private

    def product_params
      params.require(:product).permit(:name,
                                       categories_attributes: [:name, :price])
    end
end

class Category < ActiveRecord::Base
  belongs_to :product
  has_many :units, dependent: :destroy

  validates :price,    presence: true
  validates :product_id, presence: true
  validates :name,       presence: true,
                         length: { maximum: 50 }
end

所以我的产品控制器是:

class ProductsController < ApplicationController
  def new
    @product = current_brand.products.new
    @product.categories.build
  end

  def create
    @product = current_brand.products.build(product_params)
    if @product.save
      redirect_to root_url
    else
      render 'new'
    end
  end

我的新观点是这样的:

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@product) do |f| %>
      <%= render 'shared/error_messages_products' %>

      <%= f.label :name, "Name:" %>
      <%= f.text_field :name, class: 'form-control' %>
      <%= link_to_add_fields "Add Category", f, :categories %>

      <%= f.submit "Add Product", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

我的类别部分是:

<fieldset>
  <%= f.label :name, "Category Name" %>
  <%= f.text_field :name, class: 'form-control' %>

  <%= f.label :price, "Price" %>
  <%= f.text_field :price, class: 'form-control' %>
  <hr>
</fieldset>

我的应用程序助手中有link_to_add_fields助手:

module ApplicationHelper
  def link_to_add_fields(name, f, association)
    new_object = f.object.send(association).klass.new
    id = new_object.object_id
    fields = f.fields_for(association, new_object, child_index: id) do |builder|
      render(association.to_s.singularize + "_fields", f: builder)
    end
    link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
  end
end

这允许我使用一些Javascript来添加类别字段:

jQuery ->
  $('form').on 'click', '.add_fields', (event) ->
    time = new Date().getTime()
    regexp = new RegExp($(this).data('id'), 'g')
    $(this).before($(this).data('fields').replace(regexp, time))
    event.preventDefault()

但是当我尝试在此示例2中添加具有任意数量类别的产品时,我无法创建产品和类别。我从表单和对象错误中得到错误:

The form contains 1 error:
Categories product can't be blank

我从这个提示中获得的参数是:

{"utf8"=>"✓", "authenticity_token"=>"IO8GFcv1auFVh/ZNypONI78XQrY2Ntm07cMrrjmq51ogwppbsb1sNyN/ynKY+Pdb/lyniED9O6jFRkLKsvu2jQ==", "product"=>{"name"=>"Product Example", "categories_attributes"=>{"1467231299616"=>{"name"=>"Category Example 1", "price"=>"1234"}, "1467231300745"=>{"name"=>"Category Example 2", "price"=>"1234"}}}, "commit"=>"Agregar Producto", "controller"=>"products", "action"=>"create"}

我不明白为什么类别和产品没有正确关联。

1 个答案:

答案 0 :(得分:1)

经过一段时间的实验,我发现答案是从类别模型中删除product_id的验证。像这样:

<?php

require_once "lib/couch.php";
require_once "lib/couchClient.php";
require_once "lib/couchDocument.php";

$couch_dsn = "http://localhost:5984/";
$couch_db = "couch";

$client = new couchClient($couch_dsn, $couch_db);
$all_singers = null;

try {
    $all_singers = $client->include_docs(true)->getAllDocs();
} catch (Exception $e) {
    //Handle the exception here.
}
if (!isset($all_singers) || !isset($all_singers->rows))
    echo "No singers found";
else
    foreach ($all_singers->rows as $row) {
        if (isset($row->error))
            continue; //Log the error or something like this
        if (isset($row->doc)) {
            $doc = $row->doc;
            echo $doc->singer;
            echo $doc->title;
            echo $doc->description;
        }
    }