在连接条件下使用rewhere

时间:2017-04-20 16:38:00

标签: ruby-on-rails ruby-on-rails-4 activerecord

我有这段代码:

class Meeting
  has_many :attendees, class_name: 'MeetingsUsers', autosave: true

  scope :x, -> { Meeting.where(x:13) }
  scope :y, -> { Meeting.where('x':13) }
  scope :z, -> { Meeting.joins(:attendees).where('meetings_users.user_id': 123)}
end

Rewhere适用于以下情况: Meeting.x.to_sql Meeting.x.rewhere(x: 1234).to_sql Meeting.y.to_sql Meeting.y.rewhere('x': 1234).to_sql

但在这种情况下,它并没有:

Meeting.z.to_sql

生成的SQL是这样的: "SELECT \"meetings\".* FROM \"meetings\" INNER JOIN \"meetings_users\" ON \"meetings_users\".\"meeting_id\" = \"meetings\".\"id\" AND \"meetings_users\".\"deleted_at\" IS NULL WHERE \"meetings\".\"deleted_at\" IS NULL AND \"meetings_users\".\"user_id\" = 123"

随时随地:

Meeting.z.rewhere('meetings_users.user_id': 1234).to_sql

生成的SQL是这样的: "SELECT \"meetings\".* FROM \"meetings\" INNER JOIN \"meetings_users\" ON \"meetings_users\".\"meeting_id\" = \"meetings\".\"id\" AND \"meetings_users\".\"deleted_at\" IS NULL WHERE \"meetings\".\"deleted_at\" IS NULL AND \"meetings_users\".\"user_id\" = 123 AND \"meetings_users\".\"user_id\" = 1234"

正如您所看到的,在同一领域有两个条件:

"meetings_users\".\"user_id\" = 123 AND \"meetings_users\".\"user_id\" = 1234"

因此,某个神秘的原因并没有影响......

1 个答案:

答案 0 :(得分:0)

这是一个ActiveRecord错误,你可以看到: https://github.com/rails/rails/blob/v5.0.0/activerecord/lib/active_record/relation/query_methods.rb#L650

只需发送第一个哈希对象的密钥,后者就会被视为“要从caluse中删除的列”。

您可以在此处查看流程结束: https://github.com/rails/rails/blob/v5.0.0/activerecord/lib/active_record/relation/where_clause.rb#L135

他们在rails 5.0.2中更改了最后一个方法,但由于其他方法没有改变,rewhere的行为仍然是相同的。

你只能这样做:

class Meeting
  has_many :attendees, class_name: 'MeetingsUsers', autosave: true

  scope :x, -> { Meeting.where(x:13) }
  scope :y, -> { Meeting.where('x':13) }
  scope :z, -> { Meeting.joins(:attendees).where(meetings_users: {user_id: 123})}
end

query = Meeting.z
query.where_clause = query.where_clause.except('user_id')
query.where(meetings_users: {user_id: 1234})

请注意,这只适用于使用带哈希的where,因为使用字符串ll会导致ActiveRecord :: ImmutableRelation错误。