답변:
기본적인 예를 살펴 보겠습니다.
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
default를 설정하려는 동기 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"
=> Unscoped는 연결을 포함하여 (그러나 이에 국한되지는 않음) 선택 항목에 일반적으로 적용될 수있는 모든 범위를 제거합니다.
의 다양한 효과를 덮어 쓰는 방법에는 여러 가지가 있습니다 default_scope
. 그 권리를 얻는 것은 매우 빠르게 복잡해 지며 default_scope
처음에를 사용하지 않는 것이 더 안전한 선택이 될 것이라고 주장 합니다.
unscoped
대신 default_scope
이 문제 #에서
default_scope
당신이 무언가를 분류하고 싶을 때 의 좋은 사용이라고 생각합니다 : default_scope { order(:name) }
.
사용하지 않는 또 다른 이유 default_scope
는 모델과 일대 다 관계가있는 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
에서만 할 몇 가지 매개 변수를 주문에 유용하게 asc
또는 desc
모든 상황에서 순서. 그렇지 않으면 전염병처럼 피합니다