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

时间:2014-07-08 03:19:08

标签: 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 %>

现在我在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" %>

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

First argument in form cannot contain nil or be empty
到目前为止我理解的是,我需要告诉这个vendor_site控制器关于来自其他范围的@subscription。 但我无法弄清楚如何? 我的订阅类看起来像这样:

class SubscriptionsController < ApplicationController
  def new
    @subscription=Subscription.new
  end
end

3 个答案:

答案 0 :(得分:4)

您需要在此处进行一些更改。在进入详细信息之前我会建议的一件事是Rails Guides for Layouts and Rendering(和Rails Guides一般。特别是“布局和渲染指南”将帮助您极大地利用Rails的VC部分。

现在,详细介绍。首先,部分不是控制器动作。没有与之对应的控制器方法。您可以通过以下两种方式之一来尝试执行的操作,并且这两种方法都涉及首先从订阅控制器中删除new方法。

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

最简单的方法(根据您已有的更改)是在供应商站点控制器的@subscription方法中初始化index。然后,呈现的_new部分将确切知道subscription是什么。

class VendorSiteController
  def index
    @subscription = Subscription.new # add this anywhere in the index method.
  end
end

第二种方式:@subscription作为_new部分

的本地传递

这种方式将涉及对控制器,视图和部分内容的更改。在你的控制器中,你仍然需要做出我上面给出的改变。

class VendorSiteController
  def index
    @subscription = Subscription.new # add this anywhere in the index method.
  end
end

接下来,您只需删除@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 %>

最后,您需要将@subscription subscription作为<%= render :partial => "subscriptions/new", :locals => { :subscription => @subscription } %> 传递给索引视图中的部分内容。

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

虽然这种方式涉及更多变化,但它比第一种方式更灵活。例如,假设您要在页面中呈现多个新订阅:

@subscription

作为另一个示例,您可能希望将@new_sub变量名称用于新订阅以外的其他名称,而您将使用<%= render :partial => "subscriptions/new", :locals => { :subscription => @new_sub } %> 代替新订阅。

{{1}}

希望我的回答可以帮到你!如果您需要进一步说明,请随时发表评论,并确保查看那些Rails指南!

答案 1 :(得分:2)

您可以通过以下方式执行此操作,您需要在vendor_sites控制器的索引操作中初始化@subscription对象。

class VendorSiteController
   def index
     #here your showing list of vendors logic

     @subscription = Subscription.new #initialize a Subscription object
   end
end

然后你可以通过以下方式将@subscription对象传递给索引视图中的partial(对于Rails 3)

<%= render :partial => "subscriptions/new", :subscription => @subscription } %>

答案 2 :(得分:2)

Haven没有检查Joe Kennedy的回答,如果这涉及他所写的内容,请道歉:


Partials

partial的重点是,这意味着能够在您的应用程序的任何部分中使用。他们与特定控制器绑定,尤其如此,因为他们主要依靠local variables来帮助填充他们的数据

这意味着如果你想在&#34;范围之外呈现部分&#34;在控制器中,您只需要能够通过其local变量将正确的数据发送到部分数据:

#app/views/controllers/your_view.html.erb
<%= render partial: "controller/partial", locals: {variable: @value} %>

一个非常简单的例子,但希望能够证明你可以在任何你想要的地方调用部分内容。


<强> MVC

您还必须考虑MVC programming pattern,如下所述:

enter image description here

这一点的重要性在于Rails是使用MVC模式构建的 - 因为controller可以操纵data在您的视图中显示model用于收集/编译data,视图只是为了显示它

这意味着partial不应该被绑定&#34;对于特定的控制器 - 它只需要创建视图中可用的data,因此,您应该更专注于如何显示此数据,而不是必须使用特定的{{ 1}}


数据

总结到目前为止 - 你需要在任何地方放置一部分,并通过使用MVC编程模式,使用controller中的数据填充它。

现在重要的是填充controller值。这可以在视图中完成(不推荐),也可以使用各种控制器中的方法完成:

@subscription