You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails条件渲染失效:模态框显示异常问题求助

问题排查与解决方案

核心问题分析

你的模态框条件渲染反向生效,本质是@show_modal变量未按预期传递到视图:当my_student_course.size > 1时,控制器虽设置了@show_modal = true,但后续流程导致变量未被正确传递,或视图接收的变量值为nil(ERB中nil等价于false),因此<% if !@show_modal %>会触发渲染。

具体修复步骤

1. 修正控制器执行流程

控制器中mark_attendance方法在设置@show_modal后,错误调用了create_attendance(此时未选择课程,传入的my_student_course_id为nil),且未显式渲染目标视图,导致变量丢失。修改控制器代码:

def mark_attendance
  token = params[:encoded_token]
  course_id = params[:course_id]

  if token.blank?
    render json: { error: "Token is missing" }, status: :unprocessable_entity
    return
  end

  begin
    secret_key = Rails.application.credentials.secret_key_base
    payload = JWT.decode(token, secret_key, true, algorithm: "HS256")[0]
    lecturer_id = payload["lecturer_id"]
    lecturer = Lecturer.find_by(id: lecturer_id)
    
    if lecturer
      if course_id.present?
        # 处理用户选择课程后的考勤创建
        create_attendance(course_id)
        redirect_to scan_path, notice: "Attendance marked successfully"
      else
        my_student_course = lecturer.lecturer_units.flat_map(&:students_courses).uniq.select { |course| course.student_id == current_student.id }
        
        if my_student_course.size > 1
          @show_modal = true
          @students_attendance_courses = my_student_course
          # 显式渲染scan页面,确保变量传递到视图
          render :scan
        else
          my_student_course_id = my_student_course.first&.id
          create_attendance(my_student_course_id)
          redirect_to scan_path, notice: "Attendance marked successfully"
        end
      end
    else
      render json: { error: "Lecturer not found for the given lecturer_id" }, status: :unprocessable_entity
    end
  rescue JWT::DecodeError => e
    render json: { error: "Invalid token format" }, status: :unprocessable_entity
  end
end

同时确保create_attendance方法处理nil参数的情况:

def create_attendance(course_id)
  return unless course_id.present?
  # 你的考勤创建逻辑
  # ...
end

2. 修复JS的响应处理逻辑

当前JS仅处理redirect和json响应,当控制器渲染HTML视图时无法正确更新页面,修改sendPostRequest函数:

function sendPostRequest(encodedToken, csrfToken) {
  const currentUrl = window.location.href;
  const newUrl = currentUrl.replace('/scan', '/mark_attendance');
  
  fetch(newUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-Token': csrfToken,
    },
    body: JSON.stringify({ encoded_token: encodedToken }),
  })
  .then(response => {
    if (response.redirected) {
      window.location.href = response.url;
    } else if (response.headers.get('Content-Type').includes('text/html')) {
      // 处理HTML响应,更新页面内容
      response.text().then(html => {
        document.body.innerHTML = html;
      });
    } else {
      return response.json().then(data => {
        if (data.error) {
          alert(data.error);
        }
      });
    }
  })
  .catch(error => {
    console.error('Error:', error);
    alert('An error occurred while marking attendance');
  });
}

3. 优化模态框视图逻辑

移除模态框partial中的重复条件判断,添加课程选择表单:

<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="exampleModalLabel">Select Your Course</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <%= form_tag mark_attendance_path, method: :post do %>
          <% @students_attendance_courses.each do |course| %>
            <div class="form-check">
              <%= radio_button_tag 'course_id', course.id, false, class: 'form-check-input' %>
              <%= label_tag "course_id_#{course.id}", course.name, class: 'form-check-label' %>
            </div>
          <% end %>
          <%= hidden_field_tag 'encoded_token', params[:encoded_token] %>
          <%= submit_tag 'Mark Attendance', class: 'btn btn-primary mt-3' %>
        <% end %>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var myModal = new bootstrap.Modal(document.getElementById('exampleModal'));
    myModal.show();
  });
</script>

4. 恢复原条件渲染代码

将视图中的条件改回原逻辑:

<% if @show_modal %>
  <%= render 'modal' %>
<% end %>
<div id="scanQrCodeModal">
  <h1>Scan QR Codes</h1>
  <div class="section">
    <div id="my-qr-reader"></div>
  </div>
</div>

内容的提问来源于stack exchange,提问作者simon gideon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:14:52