如何将一个控制器的局部视图渲染到轨道上的ruby中的另一个控制器

sur*_*w55 5 ruby-on-rails partial-views

您好我正在尝试在供应商网站中实现订阅按钮,因此需要呈现具有vendor_site_id的隐藏属性的订阅表单.该表单在订阅控制器的范围内工作正常,但我需要在vendor_site/show页面中将其呈现为部分_new.html.erb.我无法弄清楚解决这个问题的方法在我自己可以任何身体建议我这个问题.

我的部分视图订阅/ _new.html.erb

<%= form_for(@subscription) do |f| %>
  <div class="field">
    <%= f.hidden_field @subscription.vendor_site_id, :value=>"1" %>
  </div>
  <%= button_tag(type: 'submit', class: "btn btn-primary") do %>
    <i class="fa fa-user fa-fw"></i> Subscribe
  <% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

现在,当我在vendor_sites/index.html.erb中呈现它时

<h3>This is vendor site with id 1 just for the testing of subscription method</h3>
<%= render :partial => "subscriptions/new" %>
Run Code Online (Sandbox Code Playgroud)

它会抛出一个错误,上面写着:

First argument in form cannot contain nil or be empty
Run Code Online (Sandbox Code Playgroud)

到目前为止我所理解的是,我需要告诉这个vendor_site控制器关于来自其他范围的@subscription.但我无法弄清楚如何?我的订阅类看起来像这样:

class SubscriptionsController < ApplicationController
  def new
    @subscription=Subscription.new
  end
end
Run Code Online (Sandbox Code Playgroud)

Joe*_*edy 4

您需要在此处进行一些更改。在详细介绍之前,我要推荐的一件事是Rails 布局和渲染指南(以及一般的Rails 指南)。特别是布局和渲染指南将为您提供 Rails 的 VC 部分的极大帮助。

现在,谈谈细节。首先,部分操作不是控制器操作。没有与之对应的控制器方法。您可以通过两种方式之一来执行您想要执行的操作,这两种方式都涉及new首先从订阅控制器中删除该方法。

第一种方法:@subscription在您的供应商站点控制器中初始化

最简单的方法(就相对于您已有的内容的更改而言)是@subscription在供应商站点控制器的index方法中进行初始化。然后,渲染的_new部分将确切地知道subscription是什么。

class VendorSiteController
  def index
    @subscription = Subscription.new # add this anywhere in the index method.
  end
end
Run Code Online (Sandbox Code Playgroud)

第二种方式:@subscription作为局部传递给_new局部

这种方式将涉及对控制器、视图和局部的更改。在您的控制器中,您仍然需要进行我上面给出的更改。

class VendorSiteController
  def index
    @subscription = Subscription.new # add this anywhere in the index method.
  end
end
Run Code Online (Sandbox Code Playgroud)

接下来,您需要@subscription在表单中创建一个局部变量,只需删除@.

<%= form_for(@subscription) do |f| %>
  <div class="field">
    <%= f.hidden_field @subscription.vendor_site_id, :value=>"1" %>
  </div>
  <!-- no changes to the button tag -->
<% end %>
Run Code Online (Sandbox Code Playgroud)

最后,您需要在索引视图中传递您的部分内容@subscriptionsubscription

<%= render :partial => "subscriptions/new", :locals => { :subscription => @subscription } %>
Run Code Online (Sandbox Code Playgroud)

虽然这种方式涉及的改动较多,但比第一种方式灵活得多。例如,假设您想在一页中呈现多个新订阅:

<% Subscription.where(condition: true).find_each do |s| %>
  <%= render :partial => "subscriptions/new", :locals => { :subscription => s } %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

作为另一个示例,也许您希望将@subscription变量名称用于新订阅以外的其他内容,并且您将改为用于@new_sub新订阅。

<%= render :partial => "subscriptions/new", :locals => { :subscription => @new_sub } %>
Run Code Online (Sandbox Code Playgroud)

希望我的回答对您有所帮助!如果您需要进一步说明,请随时发表评论,并且一定要查看这些 Rails 指南!