Можно ли удалить правило WHERE по умолчанию для отношения ActiveRecord? - PullRequest
0 голосов
/ 08 июня 2018

Короткая версия:

Есть ли способ "отсканировать" ассоциации ActiveRecord belongs_to (или других) в Rails 5.0?


Более длинная версия:

Я работаю над проектом Rails, где каждое «задание» назначается «отделу» для целей организации.В большинстве случаев отдел может быть выведен автоматически на основе сведений о задании, но есть несколько случаев, когда задание должно быть вручную назначено другому отделу.

Для решения этой проблемы я добавил department_id столбец в таблице заданий, чтобы все работало следующим образом:

  • Если department_id не равен NULL, присоедините задание к Департаменту, как обычно.
  • В противном случае вернитесь к «выведенной» логике соединения Job / Department.

Согласно документации Rails это возможно:

Могут быть случаи, когда вы захотите настроить запрос, который принадлежит own_to.Такие настройки могут быть достигнуты с помощью блока области.Например:

class Book < ApplicationRecord
  belongs_to :author, -> { where active: true },
                        dependent: :destroy
end

Вы можете использовать любой из стандартных методов запросов внутри блока области действия.

Поэтому я попытался определить отношение следующим образом (упрощено для демонстрационных целей).):

belongs_to :department, -> { unscoped.where(id: 7) }

... идея состоит в том, что .unscoped удалит логику по умолчанию where departments.id = [jobs.department_id], что позволит мне вместо этого определить пользовательское правило.

Однако это не 'на самом деле его не охватывать;сгенерированный SQL:

SELECT  `departments`.*
FROM `departments`
WHERE `departments`.`id` = 11 AND `departments`.`id` = 7
LIMIT 1

Я предполагаю, что логика WHERE по умолчанию применяется после Выполнен блок пользовательского запроса, что означает, что .unscoped не имеет никакого эффекта.


Несколько других вещей:

  • Я знаю, что мог бы просто установить department_id в «ожидаемое» значение при каждом создании нового задания.Однако это может иметь пару недостатков:
    • Мне нужно задним числом установить department_id каждого существующего задания в базе данных (что может занять достаточно много времени).
    • Если конкретный тип работы был переназначен в другой отдел по умолчанию, любые существующие работы останутся назначенными «предыдущему» отделу.
    • Аналогично, если детали работы будут обновленытак что он попадает под компетенцию другого отдела, пользователь должен будет переназначить его вручную.
  • Я знаю, что мог бы определить метод - или пользовательскую область - намодель Job вместо использования belongs_to здесь, но для целей этого вопроса скажем, что мне абсолютно необходимо сделать это через отношение ActiveRecord.

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

Вы очень тяжело боретесь с фреймворком и базой данных.

Мне нужно задним числом установить значение Department_id для каждого существующего задания в базе данных (что может занять достаточно много времени).

Да.Сделайте это.

Если задание определенного типа было переназначено в другой отдел «по умолчанию», любые существующие задания останутся назначенными «предыдущему» отделу.

Тогда, может быть, вы хотите иметь и принадлежать многим промежуточным таблицам - job_category или что-то подобное.Затем вы можете изменить задание, на которое оно указывает, и все, на что оно ссылается, будет обновлено.

Аналогично, если бы сведения об задании обновлялись так, чтобы оно попадало в компетенцию другого отделапользователь должен был бы переназначить его вручную.

Да - так что добавьте обратный вызов до / после, который увидит, что критерии были обновлены, а затем назначит соответствующее задание / категорию.

0 голосов
/ 09 июня 2018

Я думаю, что вы идете об этом немного в обратном направлении.Если у вас есть Department_id, пусть rails будут rails, а метод Department должен его вернуть.Тогда также имейте

def assumed_department
  return department || guessed_department
end

def guessed_department
  <your logic for guessing>
end

Если у вас есть набор кода, который уже использует «отдел», как я использую предполагаемый_департамент, тогда вам нужно удалить отдел_ид и добавить назначенный_департамент

belongs_to assigned_department, class: 'Department' # check the belongs_to docs

, затемвместо этого ваш department метод возвращает assigned_department || guessed_department и т. д. *

Но в основном, если у вас есть отношения, вам следует разрешить вашей базе данных быть базой данных, добавить отношение и всегда назначать его.

...