【发布时间】:2014-08-04 20:11:04
【问题描述】:
我的应用有两种模型:用户和提示。提示属于用户,也属于作为“收件人”的用户。
它的工作原理是,用户可以通过导航到他们的个人资料页面 (users#show)、填写表单(单个字段:链接)然后提交表单来向其他用户发送提示。该表单将 user_id 设置为 current_user,将 recipient_id 设置为您当前所在页面的用户。
我无法让表单在 users#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
在我的 users#show 视图中,我使用以下内容呈现表单:
<%= 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] "/users/3"
我假设这意味着在本地传递变量允许呈现表单,但不允许它与来自提示控制器的操作进行通信。换句话说,它试图运行 users#new 而不是 Tips#new。
我能够开始工作的唯一解决方案是在用户控制器中复制提示#new 操作,方法是将这一行添加到用户控制器中的 users#show 操作:
@tip = current_user.tips.build(tip_params)
但我读到这是不可取的,因为它不是 DRY,尽管我不完全确定这意味着什么。我的问题是,还有另一种更好的方法吗?允许用户从使用不同控制器的视图创建新对象的 DRY 方式是什么?
或者我是否完全以错误的方式完成这项任务?
【问题讨论】:
-
你能发布你的
showUsersController的动作
标签: ruby-on-rails forms model-view-controller