Ответ 1
Проблема 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"
= > Unyscoped удаляет ВСЕ области, которые могут нормально применяться к вашему выбору, включая (но не ограничиваясь ими) ассоциации.
Существует несколько способов перезаписать различные эффекты default_scope
. Правильное получение сложных очень быстро, и я бы сказал, что не использовать default_scope
, в первую очередь, было бы более безопасным выбором.