首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Arel + Rails 4.2导致问题(绑定丢失)

Arel + Rails 4.2导致问题(绑定丢失)
EN

Stack Overflow用户
提问于 2015-11-10 23:25:12
回答 1查看 1.5K关注 0票数 20

我们最近从Rails 4.1升级到Rails 4.2,并发现使用Arel + Activerecord的问题,因为我们得到了这种类型的错误:

代码语言:javascript
运行
复制
ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR:  bind message supplies 0 parameters, but prepared statement "" requires 8

下面是正在破坏的代码:

代码语言:javascript
运行
复制
customers = Customer.arel_table

      ne_subquery = ImportLog.where(
        importable_type: Customer.to_s,
        importable_id: customers['id'],
        remote_type: remote_type.to_s.singularize,
        destination: 'hello'
      ).exists.not

      first  = Customer.where(ne_subquery).where(company_id: @company.id)
      second = Customer.joins(:import_logs).merge(
        ImportLog.where(
          importable_type: Customer.to_s,
          importable_id: customers['id'],
          remote_type: remote_type.to_s.singularize,
          status: 'pending',
          destination: 'hello',
          remote_id: nil
        )
      ).where(company_id: @company.id)

      Customer.from(
        customers.create_table_alias(
          first.union(second),
          Customer.table_name
        )
      )

我们了解了如何通过将exists.not移动到Customer.where中,从而解决查询的第一部分(遇到相同的rails错误而没有绑定),如下所示:

代码语言:javascript
运行
复制
ne_subquery = ImportLog.where(
       importable_type: Customer.to_s,
       importable_id: customers['id'],
       destination: 'hello'
     )

     first  = Customer.where("NOT (EXISTS (#{ne_subquery.to_sql}))").where(company_id: @company.id)

这似乎是可行的,但我们在这一行代码中遇到了同样的问题:

代码语言:javascript
运行
复制
first.union(second)

每当我们运行这部分查询时,绑定就会丢失。第一和第二都是活动记录对象,但一旦我们“联合”了它们,它们就失去了绑定,就变成了动态对象。

我们尝试遍历查询并手动替换绑定,但似乎无法正常工作。我们该怎么办呢?

编辑:

我们还尝试从第一次和第二次中提取绑定值,然后手动替换它们,如下所示:

代码语言:javascript
运行
复制
union.grep(Arel::Nodes::BindParam).each_with_index do |bp, i|
  bv = bind_values[i]
  bp.replace(Customer.connection.substitute_at(bv, i))
end

但是,它失败了,因为:

代码语言:javascript
运行
复制
NoMethodError: undefined method `replace' for #<Arel::Nodes::BindParam:0x007f8aba6cc248>

这是rails github回购中提出的解决方案。

EN

回答 1

Stack Overflow用户

发布于 2017-12-28 02:02:44

我知道这个问题有点老,但这个错误听起来很熟悉。我在存储库中有一些注释和解决方案,所以我想我应该分享一下。

我们收到的错误是:

PG::ProtocolViolation: ERROR: bind消息提供了0参数,但是准备好的语句“需要1”

所以正如你所看到的,我们的情况有点不同。我们没有8个绑定值。然而,我们的单一绑定值仍在遭受重创。我改变了事物的命名,以保持它的一般性。

代码语言:javascript
运行
复制
first_level = Blog.all_comments
second_level = Comment.where(comment_id: first_level.select(:id))
third_level = Comment.where(comment_id: second_level.select(:id))

Blog.all_comments是我们具有单个绑定值的地方。这就是我们要失去的部分。

代码语言:javascript
运行
复制
union = first_level.union second_level
union2 = Comment.from(
  Comment.arel_table.create_table_alias union, :comments
).union third_level

relation = Comment.from(Comment.arel_table.create_table_alias union2, :comments)

我们创建了一个与您非常相似的联合,但我们需要合并三个不同的查询。

为了在这里得到丢失的绑定值,我们做了一个简单的赋值。最后,这件案子比你的要简单一些。然而,这可能是有帮助的。

代码语言:javascript
运行
复制
relation.bind_values = first_level.bind_values
relation

顺便说一句,这是我们在做这个工作时发现的GitHub问题。不过,这个问题发布后,它似乎没有任何更新。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33641601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档