Rails中JS代码无响应排查:回文数检测功能点击无反应
Rails回文数检测功能无响应问题排查
问题描述
我是Rails新手,开发的回文数检测功能无法正常运行。该功能应在当前页面展示检测结果,无需跳转,但点击检测按钮后无任何反应。浏览器已启用JS,JS请求返回200状态码,依赖库似乎已下载,仍需确认。
现有代码
控制器代码 (app/controllers/palindrome_controller.rb)
class PalindromeController < ApplicationController def index; end def show @number = params[:number] @error = validate_input(@number) calculate_palindrome unless @error respond_to do |format| format.js end end private def validate_input(number) return 'No number entered' if number =~ /\D/ return 'The number is already a palindrome' if number == number.reverse nil end def calculate_palindrome @number = @number.to_i @results = [] while @number.to_s != @number.to_s.reverse @results << @number @number += @number.to_s.reverse.to_i end @results << @number end end
视图代码 (app/views/palindrome/index.html.erb)
<h1>Testing the palindrome hypothesis</h1> <%= form_with url: '/palindrome/show', method: 'get', remote: true do %> <%= label_tag :number, "Enter a number:" %> <%= text_field_tag :number %> <%= submit_tag "Check" %> <% end %> <div id="results"></div>
路由代码 (config/routes.rb)
Rails.application.routes.draw do root 'palindrome#index' get 'palindrome/show', to: 'palindrome#show' end
JS视图代码 (app/views/palindrome/show.js.erb)
<% if @error %> $("#results").html("<p><%= @error %></p>"); <% else %> var table = "<table><tr><th>Step number</th><th>Current value</th></tr>"; <% @results.each_with_index do |result, index| %> table += "<tr><td><%= index + 1 %></td><td><%= result %></td></tr>"; <% end %> table += "</table>"; if ("<%= @results.last.to_s %>" == "<%= @results.last.to_s.reverse %>") { table += "<p>The hypothesis is confirmed</p>"; } else { table += "<p>The hypothesis has not been confirmed</p>"; } $("#results").html(table); <% end %>
问题排查与修复
1. 输入验证逻辑错误
validate_input方法存在两处核心问题:
- 空输入时,
number为nil,number =~ /\D/会返回nil,不会触发错误提示,反而会执行number == number.reverse,导致NoMethodError(nil没有reverse方法)。 - 错误提示与判断逻辑不匹配:
number =~ /\D/是检测非数字字符,但提示是"No number entered"。
修复后的验证方法:
def validate_input(number) return '请输入有效数字' if number.blank? || number =~ /\D/ return '该数字已经是回文数' if number == number.reverse nil end
2. JS字符串转义问题
show.js.erb中直接插入Ruby变量到JS字符串,若变量包含特殊字符(比如超大数字的格式问题),会破坏JS语法,导致脚本无法执行。必须用escape_javascript(简写j)转义。
修复后的show.js.erb:
<% if @error %> $("#results").html("<p><%= j @error %></p>"); <% else %> var table = "<table><tr><th>步骤序号</th><th>当前数值</th></tr>"; <% @results.each_with_index do |result, index| %> table += "<tr><td><%= j index + 1 %></td><td><%= j result %></td></tr>"; <% end %> table += "</table>"; if ("<%= j @results.last.to_s %>" == "<%= j @results.last.to_s.reverse %>") { table += "<p>验证成功:已得到回文数</p>"; } else { table += "<p>验证失败:未得到回文数</p>"; } $("#results").html(table); <% end %>
3. 确认jQuery依赖(关键)
Rails 6及以上版本默认不包含jQuery,而form_with remote: true和JS.ERB中的$都依赖jQuery。若未安装,JS请求返回后无法执行脚本。
安装步骤:
- 在
Gemfile中添加:
gem 'jquery-rails'
- 执行
bundle install - 在
app/javascript/application.js中导入:
import 'jquery' import 'jquery_ujs'
4. 路由与表单优化(可选)
硬编码URL容易出错,改用路由辅助方法更可靠:
- 修改路由,添加命名:
# config/routes.rb Rails.application.routes.draw do root 'palindrome#index' get 'palindrome/show', to: 'palindrome#show', as: :palindrome_check end
- 修改表单:
<h1>回文数验证工具</h1> <%= form_with url: palindrome_check_path, method: 'get', remote: true do %> <%= label_tag :number, "输入数字:" %> <%= text_field_tag :number %> <%= submit_tag "检测" %> <% end %> <div id="results"></div>
5. 避免无限循环(可选)
某些数字(如196)可能是Lychrel数,无法通过迭代生成回文数,会导致无限循环。添加迭代次数限制:
def calculate_palindrome @number = @number.to_i @results = [] max_steps = 100 # 限制最大迭代次数 max_steps.times do break if @number.to_s == @number.to_s.reverse @results << @number @number += @number.to_s.reverse.to_i end @results << @number # 检查是否达到步数限制仍未生成回文数 @error = "经过#{max_steps}次迭代仍未得到回文数" if @number.to_s != @number.to_s.reverse end
内容的提问来源于stack exchange,提问作者Ekwaron
相关产品推荐
相关产品推荐

