Odpowiedzi:
Rozważmy podstawowy przykład:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
Motywacją do ustawienia jako domyślnego published: truemoż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_scopezostanie 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_scopew pierwszej kolejności byłoby bezpieczniejszym wyborem.
unscopednie default_scopew problemie nr 2
default_scopejest, kiedy chcesz coś być posortowane: default_scope { order(:name) }.
Innym powodem, dla którego nie należy używać, default_scopejest usuwanie wystąpienia modelu, który ma relację 1 do wielu z default_scopemodelem
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.destroyusunie 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 wherew default_scope i raczej utworzyłbym dla tego zakres.
default_scopejedyny zawiera order. Takie zachowanie unscopedjest 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_scopemusi pasować do domyślnej wartości DB (np . { where(hidden_id: nil) }:)unscopedmetoda, która pozwoli Ci uniknąćdefault_scopeZależy to więc od rzeczywistych potrzeb.
I tylko znaleźć default_scopesię przydatne tylko w zamawianiu niektóre parametry się w asclub descporządek w całej sytuacji. W przeciwnym razie unikam tego jak zarazy