ArgumentError(传递给 #or 的关系必须在结构上兼容。不兼容的值:[:select])

用户2012677

这工作...

a = User.select("users.*, 1 as car_id").limit(2)
b = User.select("users.*, 1 as car_id").limit(2)
a.or(b)
>> returns a combined AR Relation

然而,

a = User.select("users.*, 1 as car_id").limit(2)
b =  User.select("users.*, 2 as car_id").limit(2)
a.or(b)
>> ArgumentError (Relation passed to #or must be structurally compatible. Incompatible values: [:select])

如果我这样做a+b,它会合并,然后转换为array,并且我想保持 AR 关系以继续对其进行查询。

当SELECT具有不同的CAR_ID值时,它无法联合。我原以为相同的列名会允许联合。

我正在模型上创建虚拟属性 (car_id),因为每组记录都需要使用不同值定义的 car_id。

如何解决错误和与虚拟属性的联合?

我想要一个 ActiveRecord 关系,而且足够有趣:

SELECT users.*, 1 as car_id
FROM users
UNION
SELECT users.*, 2 as car_id
FROM users

运行原始 sql 时工作正常。

SQL 示例:

 a.mail_for(:inbox).name

=> Mailboxer::Conversation::ActiveRecord_Relation

 a.mail_for(:inbox).to_sql

"SELECT DISTINCT mailboxer_conversations.*, '102' as mailer_id, 'Listing' as mailer_type FROM \"mailboxer_conversations\" INNER JOIN \"mailboxer_notifications\" ON \"mailboxer_notifications\".\"conversation_id\" = \"mailboxer_conversations\".\"id\" AND \"mailboxer_notifications\".\"type\" IN ('Mailboxer::Message') INNER JOIN \"mailboxer_receipts\" ON \"mailboxer_receipts\".\"notification_id\" = \"mailboxer_notifications\".\"id\" WHERE \"mailboxer_notifications\".\"type\" = 'Mailboxer::Message' AND \"mailboxer_receipts\".\"receiver_id\" = 102 AND \"mailboxer_receipts\".\"receiver_type\" = 'Listing' AND \"mailboxer_receipts\".\"mailbox_type\" = 'inbox' AND \"mailboxer_receipts\".\"trashed\" = FALSE AND \"mailboxer_receipts\".\"deleted\" = FALSE ORDER BY \"mailboxer_conversations\".\"updated_at\" DESC" 

所以我将一系列关系传递给 union_scope ...

 ar= a.mail_for(:inbox)
 br= b.mail_for(:inbox)
 cr= c.mail_for(:inbox)

combined = union_scope([[a,ar],[b, br],[c, cr])

def union_scope(*relation)
      combined = relation.first[1].none
      relation.each do |relation_set|
        mailer = relation_set[0]
        scope = relation_set[1].select("#{relation_set[1].table_name}.*, \'#{mailer.id}\' as mailer_id, \'#{mailer.class.name}\' as mailer_type")        
        combined = combined.or(scope)
      end
      combined
    end

更新:

def union_scope(*relation)
  combined = relation.first[1].none
  relation.each do |relation_set|
    mailer = relation_set[0]
    scope = relation_set[1].select("#{relation_set[1].table_name}.*, \'#{mailer.id}\' as mailer_id, \'#{mailer.class.name}\' as mailer_type")        
    combined = combined.union(scope)
  end
  conv = ::Mailboxer::Conversation.arel_table
  ::Mailboxer::Conversation.from(conv.create_table_alias(combined, :conversations).to_sql)
end

导致了这个错误:

Mailboxer::Conversation Load (5.8ms)  SELECT "mailboxer_conversations".* FROM ( SELECT DISTINCT "mailboxer_conversations".* FROM "mailboxer_conversations" INNER JOIN "mailboxer_notifications" ON "mailboxer_notifications"."conversation_id" = "mailboxer_conversations"."id" AND "mailboxer_notifications"."type" IN ('Mailboxer::Message') INNER JOIN "mailboxer_receipts" ON "mailboxer_receipts"."notification_id" = "mailboxer_notifications"."id" WHERE "mailboxer_notifications"."type" = $1 AND "mailboxer_receipts"."receiver_id" = $2 AND "mailboxer_receipts"."receiver_type" = $3 AND (1=0) ORDER BY "mailboxer_conversations"."updated_at" DESC UNION SELECT DISTINCT mailboxer_conversations.*, '102' as mailer_id, 'Listing' as mailer_type FROM "mailboxer_conversations" INNER JOIN "mailboxer_notifications" ON "mailboxer_notifications"."conversation_id" = "mailboxer_conversations"."id" AND "mailboxer_notifications"."type" IN ('Mailboxer::Message') INNER JOIN "mailboxer_receipts" ON "mailboxer_receipts"."notification_id" = "mailboxer_notifications"."id" WHERE "mailboxer_notifications"."type" = $4 AND "mailboxer_receipts"."receiver_id" = $5 AND "mailboxer_receipts"."receiver_type" = $6 ORDER BY "mailboxer_conversations"."updated_at" DESC ) "conversations"

ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR:  syntax error at or near "UNION")
LINE 1: ...ER BY "mailboxer_conversations"."updated_at" DESC UNION SELE...
                                                             ^
: SELECT "mailboxer_conversations".* FROM ( SELECT DISTINCT "mailboxer_conversations".* FROM "mailboxer_conversations" INNER JOIN "mailboxer_notifications" ON "mailboxer_notifications"."conversation_id" = "mailboxer_conversations"."id" AND "mailboxer_notifications"."type" IN ('Mailboxer::Message') INNER JOIN "mailboxer_receipts" ON "mailboxer_receipts"."notification_id" = "mailboxer_notifications"."id" WHERE "mailboxer_notifications"."type" = $1 AND "mailboxer_receipts"."receiver_id" = $2 AND "mailboxer_receipts"."receiver_type" = $3 AND (1=0) ORDER BY "mailboxer_conversations"."updated_at" DESC UNION SELECT DISTINCT mailboxer_conversations.*, '102' as mailer_id, 'Listing' as mailer_type FROM "mailboxer_conversations" INNER JOIN "mailboxer_notifications" ON "mailboxer_notifications"."conversation_id" = "mailboxer_conversations"."id" AND "mailboxer_notifications"."type" IN ('Mailboxer::Message') INNER JOIN "mailboxer_receipts" ON "mailboxer_receipts"."notification_id" = "mailboxer_notifications"."id" WHERE "mailboxer_notifications"."type" = $4 AND "mailboxer_receipts"."receiver_id" = $5 AND "mailboxer_receipts"."receiver_type" = $6 ORDER BY "mailboxer_conversations"."updated_at" DESC ) "conversations"
工程师

虽然我无法回答您关于为什么这些不兼容的实际问题,但我可以提供类似于您的原始 SQL 示例的解决方案。

您可以像这样执行相同的操作

user_table = User.arel_table
a = user_table.project(Arel.star, Arel.sql("1 as car_id")).take(2)
b = user_table.project(Arel.star, Arel.sql("2 as car_id")).take(2)
union = Arel::Nodes::UnionAll.new(a,b)
User.from(Arel::Nodes::As.new(union,user_table)) 

这将导致以下查询。

SELECT 
  users.* 
FROM 
  ( (SELECT  *, 1 as car_id 
     FROM users  
     ORDER BY 
       users.id ASC 
     LIMIT 2) UNION ALL (
     SELECT  *, 2 as car_id 
     FROM users  
     ORDER BY 
       users.id ASC 
     LIMIT 2)) AS users

由于这仍然会返回一个ActiveRecord::Relation您仍然可以像对待任何其他对象一样对这个对象进行操作,我们只是用您的同名自定义联合数据源替换了普通数据源(用户表)。

根据极端修订和一些关于您实际打算做什么的一般假设进行更新

a= a.mail_for(:inbox)
b= b.mail_for(:inbox)
c= c.mail_for(:inbox)


combined = union_scope(a,b,c)

def union_scope(*relations)
  base = build_scope(*relations.shift)
  combined = relations.reduce(base) do |memo, relation_set|
    Arel::Nodes::UnionAll.new(memo,build_scope(*relation_set))
  end
  union = Arel::Nodes::As.new(combined,::Mailboxer::Conversation.arel_table)
  ::Mailboxer::Conversation.from(union)
end
def build_scope(mailer,relation)
   relation.select(
      "#{relation.table_name}.*, 
      '#{mailer.id}' as mailer_id, 
      '#{mailer.class.name}' as mailer_type"
   ).arel 
end

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

(ArgumentError)参数错误-尝试将值列表传递给变更集时

来自分类Dev

使用react-select将值传递给状态

来自分类Dev

将<select> HTML标记中的选定值传递给JAVASCRIPT

来自分类Dev

如何将列表值传递给 SQL Select 查询?

来自分类Dev

Rails 上的 select_tag 中的 ArgumentError

来自分类Dev

不兼容的指针类型,将short *传递给short *(*)[]

来自分类Dev

将'float(float)'传递给不兼容类型'float'的参数

来自分类Dev

将void传递给不兼容类型的参数?

来自分类Dev

ORACLE SQL:使用SELECT语句将值传递给函数参数

来自分类Dev

如何解决将select的值传递给服务器的问题?

来自分类Dev

为什么不使用react和javascript将值传递给Select组件?

来自分类Dev

PHP SQL 表单 - 如何将值传递给下一个 Select

来自分类Dev

尝试将选定的值从 select 传递给函数,在数组中 n 次

来自分类Dev

在 Ruby on Rails 中将 option_for_select 值作为参数传递给 link_to

来自分类Dev

将表变量传递给SELECT函数

来自分类Dev

动态将columnNames传递给cassandraTable()。select()

来自分类Dev

将lambda作为变量传递给.Select()

来自分类Dev

将参数传递给MyBatis @Select

来自分类Dev

UJS,AJAX,Rails 4,form_for collection_select将值传递给方法并将值返回给表单

来自分类Dev

UJS,AJAX,Rails 4,form_for collection_select将值传递给方法并将值返回给表单

来自分类Dev

如何为<select>设置初始ng-model值以传递给函数而无需更改选择?

来自分类Dev

React-Select:如何在将HTML传递给选项中的标签值的同时保持搜索能力

来自分类Dev

将 ctypes 数组传递给 C 函数时出现 ArgumentError

来自分类Dev

将生命传递给结构

来自分类Dev

将结构传递给线程

来自分类Dev

变量不传递给函数或不传递给函数

来自分类Dev

将'NSString * __ strong'传递给不兼容类型'CLLocationDegrees'(又名'double')的参数

来自分类Dev

Xcode错误:“将'float'传递给不兼容类型ID的参数”

来自分类Dev

不兼容的指针类型将“char [3]”传递给“FILE *”类型的参数

Related 相关文章

  1. 1

    (ArgumentError)参数错误-尝试将值列表传递给变更集时

  2. 2

    使用react-select将值传递给状态

  3. 3

    将<select> HTML标记中的选定值传递给JAVASCRIPT

  4. 4

    如何将列表值传递给 SQL Select 查询?

  5. 5

    Rails 上的 select_tag 中的 ArgumentError

  6. 6

    不兼容的指针类型,将short *传递给short *(*)[]

  7. 7

    将'float(float)'传递给不兼容类型'float'的参数

  8. 8

    将void传递给不兼容类型的参数?

  9. 9

    ORACLE SQL:使用SELECT语句将值传递给函数参数

  10. 10

    如何解决将select的值传递给服务器的问题?

  11. 11

    为什么不使用react和javascript将值传递给Select组件?

  12. 12

    PHP SQL 表单 - 如何将值传递给下一个 Select

  13. 13

    尝试将选定的值从 select 传递给函数,在数组中 n 次

  14. 14

    在 Ruby on Rails 中将 option_for_select 值作为参数传递给 link_to

  15. 15

    将表变量传递给SELECT函数

  16. 16

    动态将columnNames传递给cassandraTable()。select()

  17. 17

    将lambda作为变量传递给.Select()

  18. 18

    将参数传递给MyBatis @Select

  19. 19

    UJS,AJAX,Rails 4,form_for collection_select将值传递给方法并将值返回给表单

  20. 20

    UJS,AJAX,Rails 4,form_for collection_select将值传递给方法并将值返回给表单

  21. 21

    如何为<select>设置初始ng-model值以传递给函数而无需更改选择?

  22. 22

    React-Select:如何在将HTML传递给选项中的标签值的同时保持搜索能力

  23. 23

    将 ctypes 数组传递给 C 函数时出现 ArgumentError

  24. 24

    将生命传递给结构

  25. 25

    将结构传递给线程

  26. 26

    变量不传递给函数或不传递给函数

  27. 27

    将'NSString * __ strong'传递给不兼容类型'CLLocationDegrees'(又名'double')的参数

  28. 28

    Xcode错误:“将'float'传递给不兼容类型ID的参数”

  29. 29

    不兼容的指针类型将“char [3]”传递给“FILE *”类型的参数

热门标签

归档