滚动多个嵌套表单

问题描述 投票:0回答:1

这是我的第一个Rails项目,我正在尝试创建一个表单来添加可以具有多个属性名称和值对的产品。我遵循了一些教程,并在此处查看了有关嵌套表单的几个答案,但是我对信息是否真正保存和显示信息感到困惑。我使用Cocoon gem动态创建其他属性名称和值对。我尝试使用简单的嵌套形式来确保正确构造了模型-这是下面的代码。我在下面的项目中包含了相关的代码。任何帮助是极大的赞赏!

controllers / products_controller.erb

class ProductsController < ApplicationController
  def index
    @products = Product.all
    gon.products = Product.all
  end

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

  def new
    @product = Product.new
    @properties = @product.properties.build
    @product_properties = @properties.product_properties.build
  end

  def create
    @product = Product.new(product_params)

    if @product.save
    redirect_to products_path,
    notice: 'The product was successfully created.'
    else
      render 'new'
    end
  end

  private
  def product_params
    params.require(:product).permit(:name, :upc, :available_on,
      :properties_attributes => [:property_name,
        :product_properties_attributes => [:value]
        ])
  end
  def get_property
    @property = Property.find(params[:property_id])
  end
end

models / product.rb

class Product < ApplicationRecord
  has_many :properties
  has_many :product_properties,
           :through => :properties
  accepts_nested_attributes_for :properties
  accepts_nested_attributes_for :product_properties
  attr_accessor :properties_attributes,
                :product_properties_attributes

  validates :name, :upc, :available_on, presence: true
  validates :name, :upc, uniqueness: true
  validates :upc, numericality: { only_integer: true }

  validates :name, length: { maximum: 1024,
    too_long: "%{count} characters is the maximum allowed" }


  validate :check_length

  def check_length
    unless upc.size == 10 or upc.size == 12 or upc.size == 13
      errors.add(:upc, "length must be 10, 12, or 13 characters")
    end
  end

  validate :expiration_date_cannot_be_in_the_past

  def expiration_date_cannot_be_in_the_past
    errors.add(:available_on, "must be a future date") if
      !available_on.blank? and available_on < Date.today
  end

end

models / property.rb

class Property < ApplicationRecord
  belongs_to :product
  has_many :product_properties
  accepts_nested_attributes_for :product_properties
  attr_accessor :property_name,
                :value,
                 :product_properties_attributes


  validates :property_name, presence: true
  validates :property_name, uniqueness: true
  validates :property_name, length: { maximum: 255,
    too_long: "%{count} characters is the maximum allowed" }
end

models / product_property.rb

class ProductProperty < ApplicationRecord
  belongs_to :property
  belongs_to :product
  attr_accessor :value

  validates :value, presence: true
  validates :value, length: { maximum: 255,
    too_long: "%{count} characters is the maximum allowed" }

end

views / products / new.html.erb

<h1>New Product</h1>
<%= form_with scope: @product, url: products_path, local: true do |f| %>

<% if @product.errors.any? %>
   <div id="error_explanation">
     <h2>
       <%= pluralize(@product.errors.count, "error") %> prohibited
       this product from being saved:
     </h2>
     <ul>
       <% @product.errors.full_messages.each do |msg| %>
         <li><%= msg %></li>
       <% end %>
     </ul>
   </div>
 <% end %>

  <p>
    <strong>Name</strong><br>
    <%= f.text_field :name %>
  </p>

  <p>
    <strong>UPC</strong><br>
    <%= f.text_field :upc %>
  </p>

  <p>
    <strong>Available On</strong><br>
    <%= f.date_field :available_on %>
  </p>

  <h3>Properties</h3>
  <div id='properties'>
    <%= f.fields_for (:properties) do |property| %>
      <%= property.fields_for (:product_properties) do |product_property| %>
      <p>
        <strong>Property Name</strong><br>
        <%= property.text_field :property_name %>
      </p>

      <p>
        <strong>Property Value</strong><br>
        <%= product_property.text_field :value %>
      </p>
     <% end %>
<% end %>
  </div>


  <p>
    <%= f.submit "Add Product" %>
  </p>
<% end %>

views / products / index.html.erb

<h1>Products</h1>

<%= link_to 'New Product', new_product_path %>

<div id="search"></div>

<table>
  <tr>
    <th>Name</th>
    <th>UPC</th>
    <th>Available On</th>
    <th></th>
  </tr>

  <% @products.each do |product| %>
    <tr>
      <td><%= product.name %></td>
      <td><%= product.upc %></td>
      <td><%= product.available_on %></td>
       <% product.properties.each do |property| %>
       <td><%= property.property_name %></td>
       <% end %>
      <td><%= link_to 'Details', product_path(product) %></td>
    </tr>
  <% end %>
</table>
ruby-on-rails ruby nested-forms cocoon-gem
1个回答
0
投票

新的form_with结合了先前的form_forform_tag,一方面使其功能强大,但有时也非常令人困惑。过去只是form_for @product,现在您have编写

form_with model: @product, ...

您对scope:的使用只是使用@product作为前缀,实际上不会迭代或使用@product查找关联,这就是为什么我们看不到property_attributes或隐式id的原因字段,即使您正确地具有accepts_nested_attributes(如果要返回动态添加/删除嵌套项的功能,_destroy字段也将由茧的link_to_remove_association添加)。

© www.soinside.com 2019 - 2024. All rights reserved.