我的应用有两种型号:用户和提示。提示属于用户,也属于"收件人"。
它应该如何工作,是用户可以通过导航到他们的个人资料页面(用户#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方式允许用户从使用不同控制器的视图中创建新对象?
或者我完全以错误的方式完成这项任务?
答案 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} %>
多数民众赞成!