为什么我的 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 文件并因此将两个部分呈现到视图中)如何将 @stagestage 的不同值传递给当这两个部分被同一个控制器动作渲染时?

编辑 - 添加显示视图

根据 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')