2017-02-08 55 views
1

我在Conversation模型上有一个范围,它维护2个用户之间的消息封装。我创建了一个范围来帮助检测两个用户对象的“对话”(查找或检查是否存在)。Database Arnostic'或'Query in Rails 4.2 Active Record

我曾经有:

validates_uniqueness_of :from, scope: :to 
scope :between, -> (from,to) { where('("conversations"."from" = ? AND "conversations"."to" = ?) OR ("conversations"."from" = ? AND "conversations"."to" = ?)', from, to, to, from) } 

不过,虽然这工作了SQLite和Postgres的;它不适用于MySQL。我需要将这个显式查询转换为完全不依赖于数据库,或者将其转换为活动记录关系。

我自己用'.or'自己做了一个镜头,但我怀疑这只能从Rails 5+中获得,因为当我尝试使用它时,它给了我一个未定义的方法错误。

相反,我已经使用:

validates_uniqueness_of :from, scope: :to 
scope :between, -> (from,to) { where(from: [from, to], to: [to, from]) } 

此代码的伟大工程(和它居然真的快而简洁的),但我很担心,这可能是“弱” - 在技术上是可以允许的情况从==从,从==从 - 这应该是我的应用程序不可能的。

如果在'X'和'Y'之间创建对话,则from: X and to: Y = conversation_id: 3如果Y消息X,则它应该找到conversation_id:3(因为它们在语义上是相同的)。

林很愿意离开新天地“”之间是的,但我该如何加强验证,以确保from != to记录被创建时(再没关系,查询可能有可能找到与同一用户的对话)。

+0

如何添加自定义的活动记录验证? – emaillenin

+0

我从来没有这样做过...... – Ash

回答

1

你可以尝试rails_or,支持#OR方法在Rails 3中,4个宝石,5

然后写你的范围为:

scope :between, -> (from,to) { where(from: from, to: to).or(from: to, to: from) } 
+0

是的,我想这样做没有另一颗宝石。 – Ash

+0

由于#or只是在Rails 5中添加的,所以您可能必须编写以前的原始查询。 –

+0

我升级到Rails 5,这不再是问题。 – Ash

相关问题