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

Ruby中使用<<-SQL编写查询如何传参并返回ActiveRecord Relation?

问题1:SQL块中变量的正确引用方式
  • 你当前的变量引用语法是错误的,Ruby的heredoc语法不会自动识别SQL语句内部的my_limit、my_offset为外部传入的变量,执行时会被当做SQL常量/字段名处理,直接报错。
  • 禁止直接使用#{my_limit}这类字符串插值方式注入变量,会存在严重的SQL注入风险,需要用Rails提供的参数绑定能力安全传入变量,参考写法:
# 用占位符做参数绑定
bound_sql = ActiveRecord::Base.sanitize_sql_array([
  <<~SQL, my_limit, my_offset
    SELECT *
    FROM my_table
    ORDER BY id
    LIMIT ?
    OFFSET ?
  SQL
])
  • 额外提示:你当前写的SQL语句顺序有误,ORDER BY id需要放在LIMIT、OFFSET之前,否则会触发SQL语法错误。
问题2:返回MyTable模型对应的Relation对象
  • 不要使用MyTable.find_by_sql执行上述SQL,该方法返回的是模型实例数组,不是Relation对象,无法后续链式调用ActiveRecord查询方法。
  • 根据你的场景,推荐两种实现方案:
    • 方案1(优先推荐):无需手写原生SQL,直接使用ActiveRecord内置查询方法链式调用,天然返回Relation对象:
    def get_relation(my_offset, my_limit)
      MyTable.order(id: :asc).limit(my_limit).offset(my_offset)
    end
    
    • 方案2(必须使用自定义原生SQL的场景):将绑定好参数的原生SQL作为子查询,通过from方法构建Relation:
    def get_relation(my_offset, my_limit)
      bound_sql = ActiveRecord::Base.sanitize_sql_array([
        <<~SQL, my_limit, my_offset
          SELECT *
          FROM my_table
          ORDER BY id
          LIMIT ?
          OFFSET ?
        SQL
      ])
      MyTable.from("(#{bound_sql}) AS my_tables")
    end
    

内容的提问来源于stack exchange,提问作者amggg013

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:39:00