Rails 4:在使用不同控制器的视图上渲染新操作

时间:2014-08-04 20:11:04

标签: ruby-on-rails forms model-view-controller

我的应用有两种型号:用户和提示。提示属于用户,也属于"收件人"。

它应该如何工作,是用户可以通过导航到他们的个人资料页面(用户#show),填写表单(单个字段:链接)然后提交表单来向另一个用户发送提示。表单将user_id设置为current_user,将recipient_id设置为您当前所在页面的用户。

我无法在用户#show页面上显示表单,并在加载时正常运行。

来自我的提示控制器:

def new
 @tip = current_user.tips.build
end

def create
 @tip = current_user.tips.build(tip_params)
 @tip.recipient_id = @user

 respond_to do |format|
  if @tip.save
     format.html { redirect_to @tip, notice: 'Tip was successfully created.' }
     format.json { render :show, status: :created, location: @tip }
   else
     format.html { render :new }
     format.json { render json: @tip.errors, status: :unprocessable_entity }
   end
 end
end

在我的用户#show view我正在使用以下内容呈现表单:

<%= render '/tips/form' %>

这是表单代码:

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

      <ul>
      <% @tip.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :link %><br>
    <%= f.text_field :link %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

当我尝试运行该应用时,出现以下错误:

First argument in form cannot contain nil or be empty
Extracted source (around line #1):
<%= form_for(@tip) do |f| %>

我收集的是因为tip变量没有被实例化。我尝试在渲染时将局部变量传递给表单,如下所示:

<%= render '/tips/form', locals: {tip: current_user.tips.build} %>

允许表单在页面上呈现,但当我尝试提交表单时,我得到:

路由错误:没有路由匹配[POST]&#34; / users / 3&#34;

我假设这意味着在本地传递变量允许渲染表单但不允许它与tip控制器中的操作进行通信。换句话说,它正在尝试运行用户#new而不是提示#new。

我能够开始工作的唯一解决方案是通过在用户控制器中向用户#show action添加此行,为用户复制控件中的提示#new action:

@tip = current_user.tips.build(tip_params)

但是我读到这是不可取的,因为它不是干的,虽然我不完全确定这意味着什么。我的问题是,还有另一种更好的方法吗?什么是DRY方式允许用户从使用不同控制器的视图中创建新对象?

或者我完全以错误的方式完成这项任务?

1 个答案:

答案 0 :(得分:0)

替换

<%= form_for(@tip) do |f| %>

<%= form_for(tip) do |f| %>

<%= render '/tips/form', locals: {tip: current_user.tips.build} %>

可以

<%= render :partial => '/tips/form', locals: {tip: current_user.tips.build} %>

多数民众赞成!