Проблема 1
Давайте рассмотрим основной пример:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
Мотивация использовать значение по умолчанию published: true
может заключаться в том, чтобы убедиться, что вы должны быть явным, когда хотите показывать неопубликованные (частные) сообщения. Все идет нормально.
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
Что ж, это в значительной степени то, что мы ожидаем. Теперь попробуем:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
И вот у нас есть первая большая проблема с областью действия по умолчанию:
=> default_scope повлияет на инициализацию вашей модели
Во вновь созданном экземпляре такой модели default_scope
будет отражен. Поэтому, хотя вы, возможно, хотели быть уверены, что случайно не перечислили неопубликованные сообщения, теперь вы создаете опубликованные по умолчанию.
Проблема 2
Рассмотрим более сложный пример:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Получим первые сообщения пользователей:
2.1.1 :001 > User.first.posts
Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't' AND "posts"."user_id" = ? [["user_id", 1]]
Это похоже на ожидаемое (обязательно прокрутите страницу до конца вправо, чтобы увидеть часть о user_id).
Теперь мы хотим получить список всех сообщений - включая неопубликованные - скажем, для просмотра вошедшего в систему пользователя. Вы поймете, что вам нужно «перезаписать» или «отменить» эффект default_scope
. После быстрого поиска в Google вы, вероятно, узнаете о unscoped
. Посмотрим, что будет дальше:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Без области действия удаляет ВСЕ области, которые обычно могут применяться к вашему выбору, включая (но не ограничиваясь) ассоциации.
Есть несколько способов перезаписать различные эффекты default_scope
. Получение этого права очень быстро усложняется, и я бы сказал, что не использовать default_scope
вообще, было бы более безопасным выбором.
unscoped
вместоdefault_scope
в проблеме # 2default_scope
, когда вы хотите что - то для сортировки:default_scope { order(:name) }
.Еще одна причина не использовать
default_scope
- это когда вы удаляете экземпляр модели, который имеет отношение 1 ко многим сdefault_scope
моделью.Рассмотрим, например:
Вызов
user.destroy
удалит все существующие сообщенияpublished
, но не удалит сообщения, которые естьunpublished
. Следовательно, база данных вызовет нарушение внешнего ключа, поскольку она содержит записи, которые ссылаются на пользователя, которого вы хотите удалить.источник
default_scope часто не рекомендуется, потому что он иногда неправильно используется для ограничения набора результатов. Хорошее использование default_scope - это упорядочить набор результатов.
Я бы не стал использовать
where
default_scope и скорее создал бы для этого область.источник
default_scope
только содержитorder
. Такое поведениеunscoped
довольно неожиданно.Для меня это не плохая идея , но следует использовать с осторожностью !. Есть случай, когда я всегда хотел скрыть определенные записи, когда поле установлено.
default_scope
должен соответствовать значению БД по умолчанию (например:{ where(hidden_id: nil) }
)unscoped
способ избежать вашегоdefault_scope
Так что это будет зависеть и от реальных потребностей.
источник
Я только найти ,
default_scope
чтобы быть полезным только в заказе некоторых параметров , чтобы быть вasc
илиdesc
порядок во всей ситуации. В противном случае я избегаю этого как чумыисточник