简体   繁体   中英

Database Agnostic 'or' Query in Rails 4.2 Active Record

I have a scope on a Conversation model which maintains an encapsulation of messages between 2 users. I created a scope to help detect a 'Conversation' (to find or check exist) from two user objects.

I used to have:

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) }

However, while this worked for SQLite and Postgres; it wasn't working for MySQL. I need to convert this explicit query to either be completely database agnostic, or to be made out of active record relations instead.

I have had a shot at doing it myself using '.or' but I suspect this is only available from Rails 5+ because it gave me a undefined method error when I tried to use it.

Instead I have used:

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

This code works great (and its actually really fast and succinct) but I am worried that it might be 'weak' - in that technically it could allow for a situation where from == from, to == from - which is supposed to be impossible for my application.

If a conversation is created between 'X' and 'Y', then from: X and to: Y = conversation_id: 3 and if Y messages X, then it should find conversation_id: 3 (since semantically they are the same).

Im happy enough to leave the new 'between' scope as is, but how can I strengthen the validation to ensure that from != to when the records are created (and then it doesn't matter that the query could potentially find conversations to and from the same user).

You could try rails_or , a gem which supports #or method in Rails 3, 4, 5.

Then write your scope as:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM