#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
Я имею дело с ситуацией с рефакторингом запущенного приложения с Ruby on Rails.
В приложении у меня есть пользователь, профиль которого может быть активным / неактивным.
У пользователя тоже есть дата его рождения. И для всех пользователей, которым меньше 13 лет, учетные записи должны вести себя как «неактивные».
Я только что добавил логическое свойство is_active в пользовательскую модель.
Вопрос в том, что я не хочу реорганизовывать ВСЕ мои запросы к пользователям в приложении, добавляя
User.where(is_active: true).where(age > 13)
Вручную по всем моделям
Я хочу использовать какой-нибудь другой метод, возможно, функцию обратного вызова в пользовательской модели или в контроллере.
Что вы предлагаете?
Комментарии:
1. Вы можете использовать
default_scope
. Но в долгосрочной перспективе вы можете столкнуться с некоторыми проблемами, поэтому проводите соответствующие исследования2.Я бы предложил добавлять область видимости и обновлять везде, где требуется, вместо добавления
default_scope
rails-bestpractices.com/posts/2013/06/15/default_scope-is-evil — В этой статье объясняется, почему мы должны избегатьdefault_scope
3. @SampatBadhe да, именно ту ссылку, которую я искал, чтобы добавить в ответ 🙂
4. @fernando-maymone пожалуйста, примите во внимание ссылку выше при использовании области по умолчанию
5. Честно говоря, хотя представленные простые решения будут работать, вы можете захотеть изучить политики авторизации в качестве решения. Существуют библиотеки, подобные
cancancan
иpundit
, которые предоставляют подобную функциональность и с точки зрения приложения, как правило, гораздо более удобны в обслуживании, чем использование модели.
Ответ №1:
default_scope — это то, что вам нужно, если вы не хотите изменять уже написанные запросы, но хотите добавить условие по умолчанию
class User < ActiveRecord::Base
default_scope { where(is_active: true).where("age > 13") }
end
ПРИМЕЧАНИЕ: default_scope
не рекомендуется использовать, поэтому проведите соответствующее исследование
Решение 2:
Вам нужно будет добавить область один раз во все места, где вы выполняете запросы в таблице users
class User < ActiveRecord::Base
scope :active, -> { where(is_active: true).where("age > 13") }
end
и используйте его
User.active.where(...)
возможно, вам придется выполнить вышеуказанные условия при объединении моделей