Odpowiedzi:
Rozważmy podstawowy przykład:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
Motywacją do ustawienia jako domyślnego published: true
może być upewnienie się, że musisz być jawny, gdy chcesz pokazać niepublikowane (prywatne) posty. Na razie w porządku.
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
Cóż, tego właśnie oczekujemy. Teraz spróbujmy:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
I tu mamy pierwszy duży problem z domyślnym zakresem:
=> default_scope wpłynie na inicjalizację twojego modelu
W nowo utworzonej instancji takiego modelu default_scope
zostanie odzwierciedlone. Więc chociaż możesz chcieć nie wyświetlać przypadkowo niepublikowanych postów, teraz domyślnie tworzysz opublikowane.
Rozważmy bardziej rozbudowany przykład:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Pozwala uzyskać pierwsze posty użytkowników:
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]]
Wygląda to zgodnie z oczekiwaniami (pamiętaj, aby przewinąć całą drogę w prawo, aby zobaczyć część dotyczącą user_id).
Teraz chcemy uzyskać listę wszystkich postów - w tym niepublikowanych - powiedzmy dla zalogowanego użytkownika. Zrozumiesz, że musisz „nadpisać” lub „cofnąć” efekt default_scope
. Po krótkim wygooglowaniu prawdopodobnie się dowiesz unscoped
. Zobacz, co będzie dalej:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Bez zakresu usuwa WSZYSTKIE zakresy, które normalnie mogą mieć zastosowanie do twojego wyboru, w tym (ale nie tylko) skojarzenia.
Istnieje wiele sposobów nadpisywania różnych efektów pliku default_scope
. Uzyskanie tego dobrze komplikuje się bardzo szybko i argumentowałbym, że nie używanie default_scope
w pierwszej kolejności byłoby bezpieczniejszym wyborem.
unscoped
nie default_scope
w problemie nr 2
default_scope
jest, kiedy chcesz coś być posortowane: default_scope { order(:name) }
.
Innym powodem, dla którego nie należy używać, default_scope
jest usuwanie wystąpienia modelu, który ma relację 1 do wielu z default_scope
modelem
Rozważmy na przykład:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
Dzwonienie user.destroy
usunie wszystkie posty, które są published
, ale nie usunie postów, które są unpublished
. Dlatego baza danych zgłosi naruszenie klucza obcego, ponieważ zawiera rekordy odnoszące się do użytkownika, którego chcesz usunąć.
default_scope jest często zalecany, ponieważ czasami jest nieprawidłowo używany do ograniczania zestawu wyników. Dobrym zastosowaniem default_scope jest uporządkowanie zestawu wyników.
Trzymałbym się z daleka od używania where
w default_scope i raczej utworzyłbym dla tego zakres.
default_scope
jedyny zawiera order
. Takie zachowanie unscoped
jest dość nieoczekiwane.
Dla mnie nie jest to zły pomysł, ale należy go używać ostrożnie !. Jest przypadek, w którym zawsze chciałem ukryć pewne rekordy, gdy pole jest ustawione.
default_scope
musi pasować do domyślnej wartości DB (np . { where(hidden_id: nil) }
:)unscoped
metoda, która pozwoli Ci uniknąćdefault_scope
Zależy to więc od rzeczywistych potrzeb.
I tylko znaleźć default_scope
się przydatne tylko w zamawianiu niektóre parametry się w asc
lub desc
porządek w całej sytuacji. W przeciwnym razie unikam tego jak zarazy