为什么我的 rails 控制器将不同的值传递给由同一操作呈现的 2 个部分?
Why is my rails controller passing different values to 2 partials rendered by the same action?
我有一个带有 SalesOpportunities 的应用程序 - 在这些应用程序下面有 SaleQualifiers(belong_to SalesOpportunity
),分为 4 个阶段("Need"、"Budget"、"Fit"、"Negotiation").我将这 4 个阶段显示为 SalesOpportunity 显示页面上的选项卡,当用户单击选项卡时,它将调用自定义控制器操作以 select 相关的 SaleQualifiers 显示在下面的窗格中。到目前为止这一切都很好,但我试图确保选项卡更新为 selected 阶段作为 "active" 选项卡 - 但这是行不通的。该窗格包含正确的信息,但选项卡不正确:
SalesOpportunity 显示控制器操作:
def show
@sales_opportunity = SalesOpportunity.find(params[:id])
session[:sales_opportunity_id] = @sales_opportunity.id
#set the SaleQualifier stages to show on the tabs
@stages = Question.order(:id).pluck(:sale_stage).uniq
@stage = @sales_opportunity.sale_status
@questions = Question.where(sale_stage: @stage)
#find any answered sale_qualifiers in this sale_stage
@sale_qualifiers = SaleQualifier.find_by_sql(["SELECT sale_qualifiers.* FROM sale_qualifiers INNER JOIN questions ON questions.id = sale_qualifiers.question_id WHERE sales_opportunity_id = ? AND questions.sale_stage = ? ", @sales_opportunity.id, @stage])
#find some unanswered sale_qualifiers and build them
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
#find the right question to render and link to the sale_qualifier
@question = Question.find(@sales_opportunity.next_question)
end
此操作只是确保在首次加载 SalesOpportunity 显示页面时设置右侧窗格。
这是根据他们的行为找到合适的 SaleQualifiers 的自定义行为:
def prospect_qualifiers
@sales_opportunity = SalesOpportunity.find_by(id: session[:sales_opportunity_id])
@stage = params[:sale_stage]
@questions = Question.where(sale_stage: @stage)
@stages = Question.order(:id).pluck(:sale_stage).uniq
@sale_qualifiers = SaleQualifier.find_by_sql(["SELECT sale_qualifiers.* FROM sale_qualifiers INNER JOIN questions ON questions.id = sale_qualifiers.question_id WHERE has_answer = 'true' AND sales_opportunity_id = ? AND questions.sale_stage = ? ", @sales_opportunity.id, @stage])
#when there's no sale_qualifiers from this sale_stage we can just select the first one according to the question and build that
if @sale_qualifiers.blank?
@question = Question.order(:id).where(sale_stage: @stage).first
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id], question_id: @question.id)
@answer = @sale_qualifier.build_answer
render :modal_form
else
#when some of the sale_qualifiers of this sale_stage exist we'll need to be more specific about which question is next
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
#find the right question to render and link to the sale_qualifier
@question = Question.find(@sales_opportunity.next_question)
render :modal_form
end
end
这将 sale_stage
作为从 link 传递给此操作的参数,并使用它来找到正确的 SaleQualifiers。
我的视图代码中有问题的部分如下:
<div id="qualifier-tabs">
<ul class="nav nav-tabs">
<%= render partial: 'shared/tabs', collection: @stages, as: :stage %>
</ul>
</div>
<div class="tab-content", id="qualifier_panel">
<%= render partial: 'shared/panel', collection: @stages, as: :stage %>
</div>
</div>
shared/tabs部分:
<% if stage == @stage %>
<li class="active"><%= link_to stage, prospect_qualifiers_sale_qualifiers_path(:sale_stage => stage), :remote => true, data: { disable_with: "Loading...", toggle: 'tab' } %></li>
<% else %>
<li><%= link_to stage, prospect_qualifiers_sale_qualifiers_path(:sale_stage => stage), :remote => true, data: { disable_with: "Loading...", toggle: 'tab' } %></li>
<% end %>
如您所见,这会将 collection: @stages as: stage
与从控制器操作传递的 @stage 变量进行比较,确定它们是否匹配 - 如果匹配,我们将其设为活动选项卡。
shared/panel
部分:
<% if stage == @stage %>
<div class="tab-pane active" id='<%=stage %>'>
<table class="table table-striped display responsive no-wrap">
<thead>
<tr>
<th>Question</th>
<th>Answer</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<!-- if a sale_qualifier exists with an answer show the following -->
<% @sale_qualifiers.each do |qual| %>
<tr>
<td><%= qual.question.question_text %></td>
<% if qual.question.answer_type == "Datetime"%>
<td><%= qual.answer.answer_text.to_date.readable_inspect %></td>
<% elsif qual.question.answer_type == "Boolean" %>
<% if qual.answer.answer_text == 'true'%>
<td>Yes</td>
<% elsif qual.answer.answer_text == 'false' %>
<td>No</td>
<% end %>
<% else %>
<td><%= qual.answer.answer_text %></td>
<% end %>
<td><%= link_to('edit', edit_sale_qualifier_path(qual), class: "btn btn-sm btn-warning", data: { disable_with: "Loading...", dismiss: 'modal' }, :remote => true )%></td>
</tr>
<% end %>
<!-- if there's no sale_qualifier with the question id then build one -->
<%= form_tag('/sale_qualifiers', :id => 'new_sale_qualifier', :class => 'form', method: :post, remote: true, data: { model: "sale_qualifier" }) do -%>
<%= fields_for :sale_qualifier do |ff| %>
<%= ff.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
<%= ff.hidden_field :question_id, :value => @question.id %>
<tr>
<td><%= @question.question_text %></td>
<td>
<%= ff.fields_for :answer_attributes do |answer| %>
<div class="form-group">
<% 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 %>
<span class="warning-block"></span>
<span class="help-block"></span>
</div>
<% end %>
</td>
<td>
<%= submit_tag "Submit", class: "btn btn-large btn-success", id: "sale_qualifier_submit", data: { disable_with: "Submitting..." }, autocomplete: 'off' %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
</div>
<% else %>
<div class="tab-pane" id='<%=stage %>'>
</div>
<% end %>
该窗格进行相同的等效测试并决定如何显示 SaleQualifiers。
这是 modal_form
代码:
$('#qualifier_tabs').html("<%= j render :partial => 'shared/tabs', collection: @stages, as: :stage %>");
$('#qualifier_panel').html("<%= j render :partial => 'shared/panel', collection: @stages, as: :stage %>");
问题是窗格显示了正确的 SaleQualifiers,但活动选项卡仍保留在 "Need" 上。如果我将 <%= @stage %>
和 <%= stage %>
输出放入选项卡部分以及面板部分,我明白了原因 - 选项卡面板始终显示 "Need" "Need" 作为输出那些 erb 片段,而窗格面板显示任何 sale_stage
实际上来自我的 prospect_qualifiers
操作。
prospect_qualifiers
操作(调用 modal_form
文件并因此将两个部分呈现到视图中)如何将 @stage
和 stage
的不同值传递给当这两个部分被同一个控制器动作渲染时?
编辑 - 添加显示视图
根据 Chloe 的要求 - 这是来自 SalesOpportunity 展示页面的展示视图(或其相关部分):
<div class="panel panel-default">
<div id="qualifier-tabs">
<ul class="nav nav-tabs">
<%= render partial: 'shared/tabs', collection: @stages, as: :stage %>
</ul>
</div>
<div class="tab-content", id="qualifier_panel">
<%= render partial: 'shared/panel', collection: @stages, as: :stage %>
</div>
</div>
我现在看到您的视图中有 <div id="qualifier-tabs">
,但 JQuery 中有 $('#qualifier_tabs')
。
我有一个带有 SalesOpportunities 的应用程序 - 在这些应用程序下面有 SaleQualifiers(belong_to SalesOpportunity
),分为 4 个阶段("Need"、"Budget"、"Fit"、"Negotiation").我将这 4 个阶段显示为 SalesOpportunity 显示页面上的选项卡,当用户单击选项卡时,它将调用自定义控制器操作以 select 相关的 SaleQualifiers 显示在下面的窗格中。到目前为止这一切都很好,但我试图确保选项卡更新为 selected 阶段作为 "active" 选项卡 - 但这是行不通的。该窗格包含正确的信息,但选项卡不正确:
SalesOpportunity 显示控制器操作:
def show
@sales_opportunity = SalesOpportunity.find(params[:id])
session[:sales_opportunity_id] = @sales_opportunity.id
#set the SaleQualifier stages to show on the tabs
@stages = Question.order(:id).pluck(:sale_stage).uniq
@stage = @sales_opportunity.sale_status
@questions = Question.where(sale_stage: @stage)
#find any answered sale_qualifiers in this sale_stage
@sale_qualifiers = SaleQualifier.find_by_sql(["SELECT sale_qualifiers.* FROM sale_qualifiers INNER JOIN questions ON questions.id = sale_qualifiers.question_id WHERE sales_opportunity_id = ? AND questions.sale_stage = ? ", @sales_opportunity.id, @stage])
#find some unanswered sale_qualifiers and build them
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
#find the right question to render and link to the sale_qualifier
@question = Question.find(@sales_opportunity.next_question)
end
此操作只是确保在首次加载 SalesOpportunity 显示页面时设置右侧窗格。
这是根据他们的行为找到合适的 SaleQualifiers 的自定义行为:
def prospect_qualifiers
@sales_opportunity = SalesOpportunity.find_by(id: session[:sales_opportunity_id])
@stage = params[:sale_stage]
@questions = Question.where(sale_stage: @stage)
@stages = Question.order(:id).pluck(:sale_stage).uniq
@sale_qualifiers = SaleQualifier.find_by_sql(["SELECT sale_qualifiers.* FROM sale_qualifiers INNER JOIN questions ON questions.id = sale_qualifiers.question_id WHERE has_answer = 'true' AND sales_opportunity_id = ? AND questions.sale_stage = ? ", @sales_opportunity.id, @stage])
#when there's no sale_qualifiers from this sale_stage we can just select the first one according to the question and build that
if @sale_qualifiers.blank?
@question = Question.order(:id).where(sale_stage: @stage).first
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id], question_id: @question.id)
@answer = @sale_qualifier.build_answer
render :modal_form
else
#when some of the sale_qualifiers of this sale_stage exist we'll need to be more specific about which question is next
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.build_answer
#find the right question to render and link to the sale_qualifier
@question = Question.find(@sales_opportunity.next_question)
render :modal_form
end
end
这将 sale_stage
作为从 link 传递给此操作的参数,并使用它来找到正确的 SaleQualifiers。
我的视图代码中有问题的部分如下:
<div id="qualifier-tabs">
<ul class="nav nav-tabs">
<%= render partial: 'shared/tabs', collection: @stages, as: :stage %>
</ul>
</div>
<div class="tab-content", id="qualifier_panel">
<%= render partial: 'shared/panel', collection: @stages, as: :stage %>
</div>
</div>
shared/tabs部分:
<% if stage == @stage %>
<li class="active"><%= link_to stage, prospect_qualifiers_sale_qualifiers_path(:sale_stage => stage), :remote => true, data: { disable_with: "Loading...", toggle: 'tab' } %></li>
<% else %>
<li><%= link_to stage, prospect_qualifiers_sale_qualifiers_path(:sale_stage => stage), :remote => true, data: { disable_with: "Loading...", toggle: 'tab' } %></li>
<% end %>
如您所见,这会将 collection: @stages as: stage
与从控制器操作传递的 @stage 变量进行比较,确定它们是否匹配 - 如果匹配,我们将其设为活动选项卡。
shared/panel
部分:
<% if stage == @stage %>
<div class="tab-pane active" id='<%=stage %>'>
<table class="table table-striped display responsive no-wrap">
<thead>
<tr>
<th>Question</th>
<th>Answer</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<!-- if a sale_qualifier exists with an answer show the following -->
<% @sale_qualifiers.each do |qual| %>
<tr>
<td><%= qual.question.question_text %></td>
<% if qual.question.answer_type == "Datetime"%>
<td><%= qual.answer.answer_text.to_date.readable_inspect %></td>
<% elsif qual.question.answer_type == "Boolean" %>
<% if qual.answer.answer_text == 'true'%>
<td>Yes</td>
<% elsif qual.answer.answer_text == 'false' %>
<td>No</td>
<% end %>
<% else %>
<td><%= qual.answer.answer_text %></td>
<% end %>
<td><%= link_to('edit', edit_sale_qualifier_path(qual), class: "btn btn-sm btn-warning", data: { disable_with: "Loading...", dismiss: 'modal' }, :remote => true )%></td>
</tr>
<% end %>
<!-- if there's no sale_qualifier with the question id then build one -->
<%= form_tag('/sale_qualifiers', :id => 'new_sale_qualifier', :class => 'form', method: :post, remote: true, data: { model: "sale_qualifier" }) do -%>
<%= fields_for :sale_qualifier do |ff| %>
<%= ff.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
<%= ff.hidden_field :question_id, :value => @question.id %>
<tr>
<td><%= @question.question_text %></td>
<td>
<%= ff.fields_for :answer_attributes do |answer| %>
<div class="form-group">
<% 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 %>
<span class="warning-block"></span>
<span class="help-block"></span>
</div>
<% end %>
</td>
<td>
<%= submit_tag "Submit", class: "btn btn-large btn-success", id: "sale_qualifier_submit", data: { disable_with: "Submitting..." }, autocomplete: 'off' %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
</div>
<% else %>
<div class="tab-pane" id='<%=stage %>'>
</div>
<% end %>
该窗格进行相同的等效测试并决定如何显示 SaleQualifiers。
这是 modal_form
代码:
$('#qualifier_tabs').html("<%= j render :partial => 'shared/tabs', collection: @stages, as: :stage %>");
$('#qualifier_panel').html("<%= j render :partial => 'shared/panel', collection: @stages, as: :stage %>");
问题是窗格显示了正确的 SaleQualifiers,但活动选项卡仍保留在 "Need" 上。如果我将 <%= @stage %>
和 <%= stage %>
输出放入选项卡部分以及面板部分,我明白了原因 - 选项卡面板始终显示 "Need" "Need" 作为输出那些 erb 片段,而窗格面板显示任何 sale_stage
实际上来自我的 prospect_qualifiers
操作。
prospect_qualifiers
操作(调用 modal_form
文件并因此将两个部分呈现到视图中)如何将 @stage
和 stage
的不同值传递给当这两个部分被同一个控制器动作渲染时?
编辑 - 添加显示视图
根据 Chloe 的要求 - 这是来自 SalesOpportunity 展示页面的展示视图(或其相关部分):
<div class="panel panel-default">
<div id="qualifier-tabs">
<ul class="nav nav-tabs">
<%= render partial: 'shared/tabs', collection: @stages, as: :stage %>
</ul>
</div>
<div class="tab-content", id="qualifier_panel">
<%= render partial: 'shared/panel', collection: @stages, as: :stage %>
</div>
</div>
我现在看到您的视图中有 <div id="qualifier-tabs">
,但 JQuery 中有 $('#qualifier_tabs')
。