2017-02-08 8 views
1

У меня есть область на модели разговора, которая поддерживает инкапсуляцию сообщений между двумя пользователями. Я создал область, которая поможет обнаружить «Разговор» (найти или проверить существует) из двух пользовательских объектов.База данных Agnostic 'или' Query in Rails 4.2. Активная запись

Я использовал, чтобы иметь:

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

Этот код прекрасно работает (и его на самом деле очень быстро и сжато), но я боюсь, что это может быть «слабой» - в том, что технически это может позволить ситуации где from == from, to == from - которое, как предполагается, невозможно для моего приложения.

Если разговор создается между 'X' и 'Y', то from: X and to: Y = conversation_id: 3 и если Y сообщений X, то он должен найти dialog_id: 3 (так как семантически они одинаковы).

Im достаточно счастлив оставить новую «между» сферой, как есть, но как я могу усилить проверку, чтобы убедиться, что 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