Rails 7.0中在JavaScript调用数据库数据报错求助
Rails 7.0 中 JavaScript 读取数据库数据报错的解决办法
问题背景
使用 Ruby on Rails 7.0 开发 Web 应用,尝试通过 id 为 contents 的 div 标签的 data 属性传递数据库数据到 JavaScript 时,无法正常访问数据字段,控制台报错提示无法读取 title 属性。
相关代码
index.html.erb
<p style="color: green"><%= notice %></p> <h1>Contents</h1> <div id="contents" data-contents="<%= @contents.to_json %>"></div> <script> var contentsHash = $('#contents').data('contents'); console.log(contentsHash[0].title); </script>
application.html.erb
<!DOCTYPE html> <html class="h-100"> <head> <title>MapTest</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <!-- CSS only --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <%= javascript_importmap_tags %> <script src="https://code.jquery.com/jquery-3.7.0.js" integrity="sha256-JlqSTELeR4TLqP0OG9dxM7yDPqX1ox/HfgiSLBj8+kM=" crossorigin="anonymous"></script> </head> <body> ... </body> </html>
问题原因
- JSON 转义问题:直接使用
@contents.to_json生成的字符串包含双引号,放在 HTML 属性中会导致字符串被截断,jQuery 的.data()无法将其正确解析为 JavaScript 对象数组,只能拿到不完整的字符串,自然无法访问[0].title。 - DOM 加载时机:Rails 7 默认启用 Turbo,内联脚本可能在 DOM 完全加载前执行,导致无法获取到目标元素的数据。
修复方案
方案一:正确转义 JSON 字符串
修改 index.html.erb 中的 div 标签,使用 Rails 内置的 json_escape 方法处理 JSON 输出,避免引号冲突:
<div id="contents" data-contents="<%= json_escape(@contents.to_json) %>"></div>
方案二:利用 Rails 自动处理 data 属性
Rails 支持直接将 Ruby 对象/数组赋值给 data-* 属性,会自动完成 JSON 转换和转义,更简洁安全:
<div id="contents" data-contents="<%= @contents %>"></div>
方案三:确保脚本在 DOM 加载后执行
针对 Turbo 环境,将脚本包裹在 turbo:load 事件中,确保元素已加载完成:
$(document).on('turbo:load', function() { var contentsHash = $('#contents').data('contents'); // 先判断数据是否存在,避免报错 if (contentsHash && contentsHash.length > 0) { console.log(contentsHash[0].title); } else { console.log('无可用内容或内容未加载'); } });
额外检查
- 确认控制器中
@contents是包含数据的数组,可在 erb 中临时添加<%= debug @contents %>查看数据是否正确传递; - 若
@contents为空数组,contentsHash[0]自然是 undefined,需确保数据库中有数据或控制器正确赋值。
内容的提问来源于stack exchange,提问作者Ununtrium113
相关产品推荐
相关产品推荐

