
朋友你好 在具有复杂逻辑的大型项目上工作并不是什么秘密,Active Record不会成为助手,而是一个负担。 想象一下,您需要以本机方式(在纯SQL中)对PostgreSQL进行非常复杂的查询,其中应存在一定数量的变量。 但是Rails中有一个令人不快的琐事,执行本机查询的功能不允许使用命名绑定。 但是有一个解决方案:)在使用Rails API 5.2 + Ruby 2.6.0 + Postgres 11的项目上测试并成功实现。
因此,有关该问题的更多信息。 允许您执行自己的SQL查询的主要方法是exec_query:
sql = 'SELECT id, name, desc FROM schema.news WHERE id=$1' bindings = [[nil, 100]] new = ActiveRecord::Base.connection.exec_query(sql, 'SQL', bindings).first
上面的例子表明,当我们试图从数据库中获取新闻时,活页夹的形成是通过一个地方来进行的,这是很温和的,它不能命名,而只能编号。 这极大地增加了本机查询的阅读和支持。 另外,您可以对模型类使用find_by_sql方法调用:
sql = 'SELECT id, name, desc FROM schema.news WHERE id=:id' new = New.find_by_sql([sql, id: 100]).first
这里的一切都更加令人愉快和易于理解。 但是问题是,如果您想执行一个简单的请求,这或多或少是可以接受的。 但是,如果请求确实很复杂,则通过模型和Active Record本身运行该请求会大大降低速度(缓慢)和性能(吞噬服务器资源)。 为什么在使用本机查询时没有命名绑定器是我的一个谜,但是有一个解决方案-编写我自己的小型包装程序,它可以非常简单地使用命名绑定程序,就像我所做的那样。
我带来了静态类的代码:
从代码中可以看到,一切都像房子的一角一样简单。 查询的工作方式如下:
sql = 'SELECT id, name, desc FROM schema.news WHERE id=:id' binding = { id: 100 } new = SqlQuery.execute(sql, binding).first
输出始终只是一个哈希。 一点解释。 execute方法采用查询字符串和带有活页夹的哈希。 显然,请求和哈希中的绑定必须匹配。 之后,我们在活页夹中循环遍历哈希,并在请求本身中将其替换为形式为$ 1,$ 2等的带编号的变量,同时创建一个带编号的值的数组,其中数组的第一个元素为$ 1,第二个为$ 2,依此类推。 然后,我们使用标准的exec_query方法执行查询,使用映射器运行响应,并将哈希中的键转换为字符。 之后,我们根据答案再次运行映射器,在该映射器中检查每个字段值以获取其中的JSON内容。 如果存在JSON并且有效,则将其转换为包含键和符号的哈希,如果该字段不是JSON,则引发异常,在该异常中我们返回值。 仅此而已。
如您所见,为了获得理想的结果,放置数百种各种宝石,浪费整体性能毫无意义。 您可以花费最少的时间和代码自己快速地编写许多必要的决策。
链接到github并使用插件切割宝石:
github.com/kirill-dan/active_sql_bindingsrubygems.org/gems/active_sql_bindings祝大家好运,很快再见。
从您自己的博客转载。 原来
在这里