2014-07-08 71 views
3

您好我想实现订阅按钮供应商的网站,所以需要呈现vendor_site_id隐藏属性的订阅表单。表单在订阅控制器的范围内工作正常,但我需要将其作为partial _new.html.erb在vendor_site/show页面中呈现。我无法找出解决这个问题的方法,任何机构都可以向我提出这个问题。如何渲染一个控制器的部分视图到Ruby on Rails的另一个控制器

我的部分观点订阅/ _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 f从其他范围。 但我无法弄清楚如何? 我的订阅类看起来是这样的:

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

因为你没有定义在vendor_sites控制器的index action'@ subscription',所以' form_for @ subscription'爆炸。 – sevenseacat

回答

3

一些改动,你需要在这里提出。在进入细节之前我会推荐的一件事是Rails Guides for Layouts and Rendering(和Rails Guides一般,特别是布局和渲染指南将极大地帮助您使用Rails的VC部分。

现在,详谈。首先,局部变量不是控制器动作,没有与之相对应的控制器方法,你可以通过两种方式之一来处理你想要做的事情,这两种方式都是先从订阅控制器中删除new方法。

第一种方式:初始化@subscription在您的供应商现场控制器

最简单的方法(相对于您已有的更改而言)是在供应商站点控制器的index方法中初始化@subscription。然后,呈现的_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 %> 

最后,你需要通过@subscriptionsubscription你的部分在你的索引视图。

<%= 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 } %> 

希望我的回答能帮助你!如果您需要进一步澄清,请随时发表评论,并务必查看这些Rails指南!

+0

感谢这个令人敬畏的答案,让我清楚了解基础知识和良好实践 – surajnew55

2

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

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

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

那么你可以通过下面的方式(对于Rails 3中)

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

没有检查Joe Kennedy的回答传递@subscription对象在索引视图中的部分,所以道歉,如果这倒是在他写的是什么:


Partials

partial的全部内容是为了能够在应用程序的任何部分使用。他们绑定到特定的控制器,因为它们主要依靠local variables以丰富他们的数据

这意味着,如果你想呈现的部分之外的控制器的“范围”,这是尤其如此,你只需要能够通过其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是m eant收集/编译data,视图仅仅是为了显示它

这意味着partial不应“捆绑”到一个特定的控制器 - 它只是需要创建data提供的意见,并作为这样,你应该更专注于如何可以显示此数据,而不是打电话给你的部分与特定controller


数据

到目前为止总结 - 你需要可以放部分任何地方,并且通过使用MVC编程模式,使用来自您的controller的数据填充它。

现在重要的是填充@subscription价值。这可以在视图(不推荐)完成,也可能使用的方法在不同的控制器来完成:

#app/views/subscriptions/_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 %> 

#app/views/controller/your_action.html.erb 
<%= render partial: "subscriptions/new", partials: {subscription: Subscription.new} %> 
+1

在您的上一个代码块中,'f.hidden_​​field @ subscription.vendor_site_id'应该是'f.hidden_​​field subscription.vendor_site_id'。你忘了拿出'@'。 –

相关问题