如何在 Rails 中的一个显示视图中放置此重复多次部分的表格?

How to place this form that repeats through a partial multiple times in one show view in Rails?

所以问题是这样的:我有一个 parent object (A) 的显示视图。这个 parent 有多个 children (B) 显示 - 通过部分 - 在 parent 的正下方。那么这个child又有children(C),又显示在它的parent下面。一览无余!

我有一种用于创建 B 的表单,它位于 A 的正下方,而且效果很好。 现在的问题是,如何制作用于在每个 B 下创建 C 的表单?

澄清一个典型的网站应该是这样的:

A
B
C
[创建 C 的表格]
B
C
C
[创建 C 的表格]
B
[创建 C 的表格]
[创建 B 的表格]

有:

routes.rb

resources :a do
  resources :b do 
    resources :c do
    end
  end
end

然后我如何让 B 工作的表单与以下控制器一起使用:

as_controller.rb

def show
    @a = A.find(params[:id])
    ## create a blank B
    @b = B.new
    @b.a_id = @a.id 
    ## and for C which doesn't work (yet)
    @c = C.new
    @c.b_id = @b.id
end

bs_controller

def create
  @b = B.new(b_params)
  ## assignment A id
  @b.a_id = params[:a_id] 
  ##
  @b.save
  redirect_to a_path(@b.a)
end

但是当我对 C 做同样的事情时 Rails 一直说找不到 B 的 id,像这样:

ActionController::UrlGenerationError in As#show

没有路由匹配 {:action=>"index", :a_id=>"12", :controller=>"cs", :b_id=>nil} 缺少必需的键:[:b_id]

虽然我做了类似的事情。只有这一次,每次 _b.html.haml 呈现 'c/form' 时都应该发生同样的情况。看起来像这样,但它是我页面中唯一不起作用的元素:

%h5 ADD C

= form_for [ @a, @b, @c ] do |f|
    %p
    = f.label :c1
    %br
    = f.text_field :c1
    %p
    = f.label :c2
    %br
    = f.text_area :c2
    %p
    = f.submit 'Submit'

再说一次,我如何在部分 B 上为 C 制作此表格,多次出现在 A 的这一展示页面中?

错误消息很好地突出了问题所在:

ActionController::UrlGenerationError in As#show

No route matches {:action=>"index", :a_id=>"12", :controller=>"cs", :b_id=>nil} missing required keys: [:b_id]

那是因为你的 As Controller...

def show
    ...
    ## create a blank B
    @b = B.new
    @b.a_id = @a.id 
    ...
end

正在为您的表单创建一个 new B,因为它是新的没有 ID。当您生成 C 表单时,在为表单生成正确的 URL 时,它必须有一个已经存在的 B 来引用,所以您有类似的东西:

<%= form_for [ existing-a, existing-b, brand-new-c ] do |f| %>

但是,您不能在控制器中定义 existing-b,因为您有不确定数量的 existing-b。您需要遍历 B 并在表单中使用块变量。

as_controller.rb

def show
    @a = A.find(params[:id])
end

A.html.erb

# Show info about the one A picked in the controller
<%= @a.name %>

# Loop through all of the A's indeterminate number of B's
<% a.bs.each do |b| %>
    <%= b.name %>

    # Show all of the current B's indeterminate number of C's
    <% b.cs.each do |c| %>
        <%= c.name %>
    <% end %>

    # One C form for the controller-selected A, the currently-looped-to B, and a brand-new C.
    <%= form_for [@a, b, C.new] do |f| %>
        #form fields...
    <% end %>
<% end %>

# One B form for the controller-selected A, and a brand-new B.
<%= form_for [@a, B.new] do |f| %>
    #form fields...
<% end %>

我知道我的模板是在 ERB 而不是 HAML 中。道歉。 :)