Відповіді:
Розглянемо основний приклад:
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воля відобразиться. Тож, хоча, можливо, ви хочете бути впевненим, що випадково не перераховуйте неопубліковані публікації, тепер ви створюєте опубліковані за замовчуванням.
Розглянемо більш детальний приклад:
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проблеми 2
default_scope, коли ви хочете що - то для сортування: default_scope { order(:name) }.
Ще одна причина , щоб не використовувати default_scope, коли ви видаляєте екземпляр моделі , яка має 1 до багатьох зв'язок з default_scopeмоделлю
Розглянемо для прикладу:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
Виклик 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. Інакше я уникаю цього, як чуми