Rails 在控制器动作中形成,在另一个视图中呈现?

Posted

技术标签:

【中文标题】Rails 在控制器动作中形成,在另一个视图中呈现?【英文标题】:Rails form in a controller action, rendered in another view? 【发布时间】:2013-05-11 19:06:00 【问题描述】:

我将详细设置我的问题之后的场景。

这里是场景:

我有一个联系人控制器,具有新的和创建的操作。这是我希望用户填写并存储他们的回复的表格。

联系控制器:

class ContactController < ApplicationController

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.new(params[:contact])
    respond_to do |format|
      if @contact.save
        format.html  redirect_to social_path, notice: 'Message sent successfully!' 
      else
       format.html  render action: 'new' 
      end
    end
  end
end

我有一个相应的 _form.html.erb 部分视图,以及一个 new.html.erb 视图,它会像您一样呈现表单部分。这些视图都位于联系人视图文件夹内,并带有相应的路由。

_form.html.erb

<%= form_for @contact do |f| %>
  <% if @contact.errors.any? %>
    <h2>
      <%= pluralize(@contact.errors.count, "error") %> prohibited this contact from being saved:
    </h2>

    <ul>
    <% @contact.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  <% end %>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :name, :class => 'inline' %>
  </div>
  <div class="large-10 columns">
    <%= f.text_field :name, :placeholder => 'Kenny Powers' %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :subject %>
  </div>
  <div class="large-10 columns">
    <%= f.text_field :subject %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :email %>
  </div>
  <div class="large-10 columns">
    <%= f.text_field :email, :placeholder => 'kennypowers@example.com' %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :message %>
  </div>
  <div class="large-10 columns">
    <%= f.text_area :message %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns end">
    <%= f.submit %>
  </div>
</div>
<% end %>

new.html.erb

我创建了一个 static_pages 控制器,因为我想让我的大部分静态页面与加载动态内容的页面分开。

在 static_pages 控制器内部,我有一个为空的社交控制器操作。我在位于 static_pages 视图文件夹中的 social.html.erb 中显示静态内容,匹配路由如下

match 'social' => 'static_pages#social'

social.html.erb

<%= render :template => 'contact/new', :@contact => Contact.new %>

static_pages_controller

def social

end

酷,社交页面完美呈现。

现在让我感到困惑的是:

如何在社交页面中呈现联系表单?因为它位于我拥有的 social.html.erb 文件中

&lt;%= render template: 'contact/new' %&gt;

这给了我

ActionView::MissingTemplate in Static_pages#social

Showing app/views/contact/new.html.erb where line #1 raised:

1: <%= render 'form' %>

它会为contact/new.html.erb 中的_form.html.erb 引发缺少模板错误。如果我尝试通过添加

来指定表单位置
<%= render 'contact/form' %>

我收到 undefined method model_name for NilClass:Class 错误。

我这样做完全错了吗?有没有更好的方法来做我正在尝试的事情?谁能给我一个外行的解释?

我知道在将表单部分渲染到其他控制器时也有类似的问题,但它们只是一种解决方案。我非常感谢支持为什么会发生这种情况的话语,或者支持更好/正确的做事方式的话语。

如果您需要更多信息/具体代码,请告诉我。

【问题讨论】:

可能_form.html.erb 正在使用一个未初始化的局部变量或实例变量。最后一条错误消息中是否有行号可以提供帮助? 查看这个问题:***.com/questions/9304368/… - 渲染表单时,您可能需要传入该部分使用的任何对象。 能否同时添加控制器代码和_form 代码。如果我们能看到代码,这听起来很容易解决问题 表单一般需要模型对象;如果没有您的表单代码或为其准备的控制器代码,很难提供帮助。一个警告标志是,如果您的路径是可信的,那么您正在尝试在“静态”页面中执行非静态操作。 @JamesDullaghan contacts_path 在您的 routes.rb 文件中需要 contacts 路由。目前尚不清楚您是否只是想以不同的姓名访问联系人,或者您是否试图将联系人作为隔离资源保留但从多个位置访问它。 【参考方案1】:

解决办法是:

将您的“social.html.erb”复制并粘贴到您的“/contact/new.html.erb”中

然后将该特定渲染更改为:

<%= render 'form' %>    # that's ok now, because you are in the right directory

现在在 routes.rb:

resources :contacts     # it's important to add this for RESTful architecture

match 'social' => 'contact#new' # and DELETE the other line with => 'contact#index' because it is no more necessary

就是这样。

更新:这是我的 github 解决方案(在您的应用程序中)

https://github.com/rubybrah/solution

【讨论】:

这是评论,不是答案。 我无法回答,我想帮忙,我还能做什么? 要么发表评论,要么什么都不做。答案应该是答案;这不是论坛,而是问答。 如果解决方案是“剪切和粘贴”,您几乎总是在解决错误的问题。 非常感谢 ruby​​brah,这是一个比我尝试做的更清洁的解决方案。

以上是关于Rails 在控制器动作中形成,在另一个视图中呈现?的主要内容,如果未能解决你的问题,请参考以下文章

在一个动作中渲染不同的视图

Rails 5,动作电缆和 current_user

如何在 3D 触摸窥视动作的预览动作中访问呈现视图控制器?

如何在 Rails 视图中呈现所有评论?

将 Javascript 数组发送到控制器并在另一个 URL 中呈现视图结果

在 Rails 中,如何使用视图呈现 JSON?