如何在 Rails 中通过对象控制器的创建操作使用对象的新实例渲染局部对象?
How can I render a partial with a new instance of my object from the create action of that object's controller in Rails?
我的应用程序中有一系列硬编码问题。 SaleQualifier 挑选每个问题,并根据答案(SaleQualifier has_one 答案)应用程序决定接下来向用户呈现哪个后续问题。
SaleQualifier belongs_to SalesOpportunity
- 以及问题和答案字段都呈现在我的 SalesOpportunity 展示页面的部分内容中。当我每次回答问题时重新加载整个页面时,这工作正常,但我想在 SaleQualifier 视图中使用 remote: true
link 和 create.js.erb
文件来呈现下一个部分没有整页刷新。
销售机会控制器:
# GET /sales_opportunities/1
# GET /sales_opportunities/1.json
def show
@sales_opportunity = SalesOpportunity.includes(:company, :user, :timeline_events, :sale_contacts, :swots, :sale_competitors).find(params[:id])
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
@question = find_current_question
end
如您所见,我正在此处设置一个新的 SaleQualifier,为其构建一个答案,并使用以下方法查找相关问题:
def find_current_question
question = Question.find(@sales_opportunity.next_question)
return question
end
部分内容如下(我试过传递局部变量,但这不起作用,因为我认为问题出在 SaleQualifier 控制器的创建操作中):
<div class="panel panel-default">
<%= form_for(@sale_qualifier, :html => {role: :form, 'data-model' => 'sale_qualifier'}, remote: true) do |f| %>
<% if @sale_qualifier.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@sale_qualifier.errors.count, "error") %> prohibited this answer from being saved:</h2>
<ul>
<% @sale_qualifier.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="panel-body">
<div class="col-sm-6">
<h2><%= @question.question_text %></h2>
</div>
<div class="col-sm-6">
<div class="form-group">
<%= f.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
</div>
<div class="form-group">
<%= f.hidden_field :question_id, :value => @question.id %>
</div>
<%= f.fields_for :answer do |answer| %>
<% if @question.answer_type == 'Text Field' %>
<%= answer.text_area :answer_text, :placeholder => "Enter your answer" %>
<% end %>
<% if @question.answer_type == 'Datetime' %>
<div class='input-group date' id='datetimepicker' data-date-format="YY.MM.DD">
<%= answer.text_field :answer_text, class: "form-control", data: { date_format: 'YYYY/MM/DD' }, :placeholder => "YYYY/MM/DD" %>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<% end %>
<% if @question.answer_type == 'Boolean' %>
<%= answer.select :answer_text, [['Yes', true], ['No', false]] %>
<% end %>
<% if @question.answer_type == 'Update' %>
<%= answer.hidden_field :answer_text, :value => "Updated" %>
<% end %>
<% end %>
<% if @question.answer_type == 'Update' %>
<div class="actions">
<%= f.submit "Done", class: "btn btn-large btn-success"%>
</div>
<% else %>
<div class="actions">
<%= f.submit "Submit", class: "btn btn-large btn-success"%>
</div>
<% end %>
<% end %>
</div>
</div>
</div>
提交后,会在后台运行一组代码来更新 SalesOpportunity,以便呈现正确的下一个问题。
我的 SaleQualifier 控制器的创建操作如下:
def create
@sale_qualifier = SaleQualifier.new(sale_qualifier_params)
@sales_opportunity = @sale_qualifier.sales_opportunity
respond_to do |format|
if @sale_qualifier.save
format.html { redirect_to @sales_opportunity, notice: 'Sale qualifier was successfully created.' }
format.json { render :show, status: :created, location: @sale_qualifier }
format.js
else
format.html { render :new }
format.json { render json: @sale_qualifier.errors, status: :unprocessable_entity }
end
end
end
我相信我的问题源于此 - 因为部分期望根据我的 SalesOpportunity show 操作中设置的定义看到 @sale_qualifier,但这里的 @sale_qualifier 指的是该模型的新保存实例。因此,当我尝试将其与 remote: true 设置一起使用时,出现以下错误:
ActionView::Template::Error (undefined method `question_text' for nil:NilClass):
12: <% end %>
13: <div class="panel-body">
14: <div class="col-sm-6">
15: <h2><%= @question.question_text %></h2>
16: </div>
17: <div class="col-sm-6">
18: <div class="form-group">
app/views/sale_qualifiers/_qualify.html.erb:15:in `block in _app_views_sale_qualifiers__qualify_html_erb__3308770490925429645_70100598754380'
app/views/sale_qualifiers/_qualify.html.erb:2:in `_app_views_sale_qualifiers__qualify_html_erb__3308770490925429645_70100598754380'
app/views/sale_qualifiers/create.js.erb:2:in `_app_views_sale_qualifiers_create_js_erb__2206693572750561934_70100598786040'
app/controllers/sale_qualifiers_controller.rb:32:in `create'
create.js.erb代码:
//update the sale qualifier div with the next question
$('#sale_qualifier_div').html("<%= escape_javascript(render :partial => 'sale_qualifiers/qualify', :locals => { :sale_qualifier => @sale_qualifier, :answer => @answer, :question => @question} )%>");
有什么方法可以将这些变量传递给这个部分吗?
我已经设法通过使用传递给 format.js 操作的块解决了这个问题(但是如果有人能告诉我为什么这是一个不好的 idea/give 我是一个更好的选择,我将不胜感激)我重置了这些实例变量:
format.js {
@sales_opportunity = SalesOpportunity.find_by(id: session[:sales_opportunity_id])
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
@question = Question.find(@sales_opportunity.next_question)
}
这个可行,但感觉 ugly/smelly。
我的应用程序中有一系列硬编码问题。 SaleQualifier 挑选每个问题,并根据答案(SaleQualifier has_one 答案)应用程序决定接下来向用户呈现哪个后续问题。
SaleQualifier belongs_to SalesOpportunity
- 以及问题和答案字段都呈现在我的 SalesOpportunity 展示页面的部分内容中。当我每次回答问题时重新加载整个页面时,这工作正常,但我想在 SaleQualifier 视图中使用 remote: true
link 和 create.js.erb
文件来呈现下一个部分没有整页刷新。
销售机会控制器:
# GET /sales_opportunities/1
# GET /sales_opportunities/1.json
def show
@sales_opportunity = SalesOpportunity.includes(:company, :user, :timeline_events, :sale_contacts, :swots, :sale_competitors).find(params[:id])
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
@question = find_current_question
end
如您所见,我正在此处设置一个新的 SaleQualifier,为其构建一个答案,并使用以下方法查找相关问题:
def find_current_question
question = Question.find(@sales_opportunity.next_question)
return question
end
部分内容如下(我试过传递局部变量,但这不起作用,因为我认为问题出在 SaleQualifier 控制器的创建操作中):
<div class="panel panel-default">
<%= form_for(@sale_qualifier, :html => {role: :form, 'data-model' => 'sale_qualifier'}, remote: true) do |f| %>
<% if @sale_qualifier.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@sale_qualifier.errors.count, "error") %> prohibited this answer from being saved:</h2>
<ul>
<% @sale_qualifier.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="panel-body">
<div class="col-sm-6">
<h2><%= @question.question_text %></h2>
</div>
<div class="col-sm-6">
<div class="form-group">
<%= f.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
</div>
<div class="form-group">
<%= f.hidden_field :question_id, :value => @question.id %>
</div>
<%= f.fields_for :answer do |answer| %>
<% if @question.answer_type == 'Text Field' %>
<%= answer.text_area :answer_text, :placeholder => "Enter your answer" %>
<% end %>
<% if @question.answer_type == 'Datetime' %>
<div class='input-group date' id='datetimepicker' data-date-format="YY.MM.DD">
<%= answer.text_field :answer_text, class: "form-control", data: { date_format: 'YYYY/MM/DD' }, :placeholder => "YYYY/MM/DD" %>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<% end %>
<% if @question.answer_type == 'Boolean' %>
<%= answer.select :answer_text, [['Yes', true], ['No', false]] %>
<% end %>
<% if @question.answer_type == 'Update' %>
<%= answer.hidden_field :answer_text, :value => "Updated" %>
<% end %>
<% end %>
<% if @question.answer_type == 'Update' %>
<div class="actions">
<%= f.submit "Done", class: "btn btn-large btn-success"%>
</div>
<% else %>
<div class="actions">
<%= f.submit "Submit", class: "btn btn-large btn-success"%>
</div>
<% end %>
<% end %>
</div>
</div>
</div>
提交后,会在后台运行一组代码来更新 SalesOpportunity,以便呈现正确的下一个问题。
我的 SaleQualifier 控制器的创建操作如下:
def create
@sale_qualifier = SaleQualifier.new(sale_qualifier_params)
@sales_opportunity = @sale_qualifier.sales_opportunity
respond_to do |format|
if @sale_qualifier.save
format.html { redirect_to @sales_opportunity, notice: 'Sale qualifier was successfully created.' }
format.json { render :show, status: :created, location: @sale_qualifier }
format.js
else
format.html { render :new }
format.json { render json: @sale_qualifier.errors, status: :unprocessable_entity }
end
end
end
我相信我的问题源于此 - 因为部分期望根据我的 SalesOpportunity show 操作中设置的定义看到 @sale_qualifier,但这里的 @sale_qualifier 指的是该模型的新保存实例。因此,当我尝试将其与 remote: true 设置一起使用时,出现以下错误:
ActionView::Template::Error (undefined method `question_text' for nil:NilClass):
12: <% end %>
13: <div class="panel-body">
14: <div class="col-sm-6">
15: <h2><%= @question.question_text %></h2>
16: </div>
17: <div class="col-sm-6">
18: <div class="form-group">
app/views/sale_qualifiers/_qualify.html.erb:15:in `block in _app_views_sale_qualifiers__qualify_html_erb__3308770490925429645_70100598754380'
app/views/sale_qualifiers/_qualify.html.erb:2:in `_app_views_sale_qualifiers__qualify_html_erb__3308770490925429645_70100598754380'
app/views/sale_qualifiers/create.js.erb:2:in `_app_views_sale_qualifiers_create_js_erb__2206693572750561934_70100598786040'
app/controllers/sale_qualifiers_controller.rb:32:in `create'
create.js.erb代码:
//update the sale qualifier div with the next question
$('#sale_qualifier_div').html("<%= escape_javascript(render :partial => 'sale_qualifiers/qualify', :locals => { :sale_qualifier => @sale_qualifier, :answer => @answer, :question => @question} )%>");
有什么方法可以将这些变量传递给这个部分吗?
我已经设法通过使用传递给 format.js 操作的块解决了这个问题(但是如果有人能告诉我为什么这是一个不好的 idea/give 我是一个更好的选择,我将不胜感激)我重置了这些实例变量:
format.js {
@sales_opportunity = SalesOpportunity.find_by(id: session[:sales_opportunity_id])
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
@question = Question.find(@sales_opportunity.next_question)
}
这个可行,但感觉 ugly/smelly。