如何防止一个部分从同一视图中的另一个部分劫持局部变量?
How do I prevent one partial from hijacking the local variables from another in the same view?
所以我有一个 Question#Show.html.erb
具有以下内容:
<% @question.answers.each do |ans| %>
<%= render partial: "questions/answer", locals: {ans: ans} %>
<% end %>
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="ibox">
<div class="ibox-title">
<h5>Your Refactor Suggestion</h5>
</div>
<div class="ibox-content">
<%= render partial: "answers/form", locals: {answer: @question.answers.build(user: current_user)} %>
</div>
</div>
</div>
</div>
这很好用。
但是,一旦我翻转它(即将当前位于底部的 div.class=row
放在顶部的迭代器上方),我就会遇到一些疯狂的错误。
例如,这样做:
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="ibox">
<div class="ibox-title">
<h5>Your Refactor Suggestion</h5>
</div>
<div class="ibox-content">
<%= render partial: "answers/form", locals: {answer: @question.answers.build(user: current_user)} %>
</div>
</div>
</div>
</div>
<% @question.answers.each do |ans| %>
<%= render partial: "questions/answer", locals: {ans: ans} %>
<% end %>
导致此错误:
ActionController::UrlGenerationError at /questions/42
No route matches {:action=>"vote_up", :controller=>"answers", :id=>nil} missing required keys: [:id]
这是我的 questions/_answer.html.erb
部分(为简洁起见被截断):
<%= link_to vote_up_answer_path(ans), method: :post do %>
<i class="fa fa-chevron-up"> </i>
<% end %>
<%= ans.cached_votes_total %>
<%= link_to vote_down_answer_path(ans), method: :post do %>
<i class="fa fa-chevron-down"> </i>
<% end %>
<%= ans.body %>
<%= link_to ans.user.try(:email), user_path(ans.user) %>
这是我的 answers/_form.html.erb
部分(为简洁起见也被截断):
<%= simple_form_for(answer) do |f| %>
<%= f.error_notification %>
<%= f.input :question_id, as: :hidden %>
<%= f.input :user_id, as: :hidden %>
<div class="form-group">
<%= f.input_field :body, as: :text, class: "form-control", rows: 8 %>
</div>
<div class="form-group">
<%= f.input_field :language, collection: ["ruby", "python", "php"], as: :select, selected: "ruby", class: "form-control" %>
</div>
<div id="new-post-submission-button">
<%= f.button :submit, class: "btn btn-lg btn-primary pull-right" %>
</div>
<% end %>
这是我的 Questions#Show
控制器:
def show
@question = Question.includes(:answers).find(params[:id])
end
是什么导致了这种奇怪的行为?
我认为问题在于首先 构建关联的答案 (如代码的这一部分:@question.answers.build(user: current_user)
)。 build
构造一个新的关联对象(答案),将外键 link 设置到主对象(问题)并将其添加到关联集合(到问题的所有答案)。但是它还没有保存它,因此它确实还没有ID。
因此,当您为问题的答案关联的所有成员呈现部分 next 时,这也包括上面新创建的答案。在渲染部分时,您可能应该跳过新创建的答案。 更新:为此,您可以执行以下操作(实现相同的方法有很多,这只是一个示例):
@question.answers.select { |ans| ans.persisted? }.each do |ans|
...
end
所以我有一个 Question#Show.html.erb
具有以下内容:
<% @question.answers.each do |ans| %>
<%= render partial: "questions/answer", locals: {ans: ans} %>
<% end %>
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="ibox">
<div class="ibox-title">
<h5>Your Refactor Suggestion</h5>
</div>
<div class="ibox-content">
<%= render partial: "answers/form", locals: {answer: @question.answers.build(user: current_user)} %>
</div>
</div>
</div>
</div>
这很好用。
但是,一旦我翻转它(即将当前位于底部的 div.class=row
放在顶部的迭代器上方),我就会遇到一些疯狂的错误。
例如,这样做:
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="ibox">
<div class="ibox-title">
<h5>Your Refactor Suggestion</h5>
</div>
<div class="ibox-content">
<%= render partial: "answers/form", locals: {answer: @question.answers.build(user: current_user)} %>
</div>
</div>
</div>
</div>
<% @question.answers.each do |ans| %>
<%= render partial: "questions/answer", locals: {ans: ans} %>
<% end %>
导致此错误:
ActionController::UrlGenerationError at /questions/42
No route matches {:action=>"vote_up", :controller=>"answers", :id=>nil} missing required keys: [:id]
这是我的 questions/_answer.html.erb
部分(为简洁起见被截断):
<%= link_to vote_up_answer_path(ans), method: :post do %>
<i class="fa fa-chevron-up"> </i>
<% end %>
<%= ans.cached_votes_total %>
<%= link_to vote_down_answer_path(ans), method: :post do %>
<i class="fa fa-chevron-down"> </i>
<% end %>
<%= ans.body %>
<%= link_to ans.user.try(:email), user_path(ans.user) %>
这是我的 answers/_form.html.erb
部分(为简洁起见也被截断):
<%= simple_form_for(answer) do |f| %>
<%= f.error_notification %>
<%= f.input :question_id, as: :hidden %>
<%= f.input :user_id, as: :hidden %>
<div class="form-group">
<%= f.input_field :body, as: :text, class: "form-control", rows: 8 %>
</div>
<div class="form-group">
<%= f.input_field :language, collection: ["ruby", "python", "php"], as: :select, selected: "ruby", class: "form-control" %>
</div>
<div id="new-post-submission-button">
<%= f.button :submit, class: "btn btn-lg btn-primary pull-right" %>
</div>
<% end %>
这是我的 Questions#Show
控制器:
def show
@question = Question.includes(:answers).find(params[:id])
end
是什么导致了这种奇怪的行为?
我认为问题在于首先 构建关联的答案 (如代码的这一部分:@question.answers.build(user: current_user)
)。 build
构造一个新的关联对象(答案),将外键 link 设置到主对象(问题)并将其添加到关联集合(到问题的所有答案)。但是它还没有保存它,因此它确实还没有ID。
因此,当您为问题的答案关联的所有成员呈现部分 next 时,这也包括上面新创建的答案。在渲染部分时,您可能应该跳过新创建的答案。 更新:为此,您可以执行以下操作(实现相同的方法有很多,这只是一个示例):
@question.answers.select { |ans| ans.persisted? }.each do |ans|
...
end