如何在Rails 7+MySQL 8中用ActiveRecord查询JSON属性匹配数组值
解决Rails 7 + MySQL 8 JSON字段的数组匹配查询问题
要实现像普通属性where(column_name: values)那样的数组匹配查询,你需要调整JSON字段的查询语法,结合MySQL的JSON函数和SQL的IN操作符,具体方案如下:
方法1:直接使用MySQL JSON操作符 + SQL IN
使用->>操作符(它等价于JSON_UNQUOTE(JSON_EXTRACT()),能提取不带引号的JSON字符串值),配合IN来匹配数组:
titles = ['Tree','Ice','Pulp'] authors = Author.where("book->>'$.title' IN (?)", titles)
原代码失败原因
原代码用=匹配数组时,MySQL会把整个数组当作单个字符串值处理,自然匹配不到任何记录;同时->操作符返回的是带双引号的JSON字符串(比如"Tree"),和你传入的字符串Tree类型不匹配,这也是查询失败的核心原因。
方法2:使用Arel(更符合Rails风格)
用Rails的Arel构造查询,避免手写SQL片段,可读性和安全性更好:
titles = ['Tree','Ice','Pulp'] # 构造JSON字段提取并去引号的查询条件 book_title = Author.arel_table[:book].json_extract('$.title').unquote # 执行IN查询 authors = Author.where(book_title.in(titles))
方法3:利用Rails 7的JSON字段简化查询语法
如果你的Rails 7配置正确,也可以直接使用点语法查询JSON字段,Rails会自动转换为正确的SQL:
titles = ['Tree','Ice','Pulp'] authors = Author.where("book.title": titles)
注意:这种写法需要确保book属性在模型中被定义为json类型(迁移中用t.json :book),且MySQL版本支持对应的JSON函数。
额外注意事项
- 确保
book字段中的title值是字符串类型,若为数字或其他类型,需要调整匹配值的类型或查询逻辑; - 所有方案都使用了参数化查询,避免了SQL注入风险。
内容的提问来源于stack exchange,提问作者EastsideDev
相关产品推荐
相关产品推荐

