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

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>

问题原因

  1. JSON 转义问题:直接使用 @contents.to_json 生成的字符串包含双引号,放在 HTML 属性中会导致字符串被截断,jQuery 的 .data() 无法将其正确解析为 JavaScript 对象数组,只能拿到不完整的字符串,自然无法访问 [0].title。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 19:05:15