Ruby on Rails:如何编写视图来创建复合对象?

时间:2016-06-28 16:13:34

标签: ruby-on-rails ruby rails-activerecord

我正在为BouquetFlower个对象建模。我想写一个表单,允许我创建Bouquet,创建Flower个对象的实例,并将它们放在Bouquet中。

我已经模拟了以下关系。

  1. Bouquet - has_many - > Flower秒。
  2. Flower - belongs_to - > Bouquet
  3. 删除Bouquet也会从数据库中删除其中的Flower
  4. 是否有任何模式可用于创建实现上述目标的视图。

1 个答案:

答案 0 :(得分:1)

您可以使用嵌套属性来完成此操作。您的模型将具有基本的has_many / belongs_to关联设置:

# app/models/bouquet.rb
class Bouquet < ActiveRecord::Base
  has_many :flowers, dependent: :destroy
  accepts_nested_attributes_for :flowers
end

# app/models/flower.rb
class Flower < ActiveRecord::Base
  belongs_to :bouquet
end

请注意accepts_nested_attributes_for方法,该方法允许您通过Flower父级保存相关Bouquet条记录的属性。

BouquetsController的强力参数中,您可以将花束花的嵌套属性列入白名单,并从中开始构建一些空白花:

# app/controllers/bouquets_controller.rb
class BouquetsController < ApplicationController
  def new
    @bouquet = Bouquet.new
    5.times { @bouquet.flowers.build }
  end

  private

  def bouquet_params
    params.require(:bouquet).permit(:name, :size, flowers_attributes: [:color, :species])
  end
end

现在,在您的表单中,您可以使用fields_for在花束中填写鲜花信息:

<!-- app/views/bouquets/new.html.erb -->

<div class="create-form">
  <%= form_for @bouquet do |f| %>
    <%= f.label "Bouquet Name" %>  
    <%= f.text_field :name %>

    <%= f.label "Size of Bouquet" %>
    <%= f.text_field :size %>

    <%= fields_for :flower do |ff| %>
      <%= ff.label "Flower Name" %>
      <%= ff.text_field :name %>

      <%= ff.label "Species of Flower" %>
      <%= ff.text_field :species %>
    <% end %>

    <%= f.submit %>
  <% end %>
</div>

将关系名称的符号传递给fields_for,可以从该关系推断出如何在表单中呈现嵌套字段。

上面的设置允许您创建一个花束,并使其嵌套的花自动与之关联。删除花束也将删除所有花朵。您可以添加一些JS以使此表单更具动态性(例如,添加/删除单个花朵的按钮)。

希望这有帮助!