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
相关产品推荐
相关产品推荐

