[ruby-on-rails] Rails default_scope 재정의

기본 범위를 가진 ActiveRecord :: Base 모델이있는 경우 :

class Foo < ActiveRecord::Base

  default_scope :conditions => ["bar = ?",bar]

end

조건 Foo.find 사용 하지 않고 할 수있는 방법이 default_scope있습니까? 즉, 기본 범위를 재정의 할 수 있습니까?

이름에 ‘default’를 사용하면 재정의 가 가능 하다는 것을 암시한다고 생각 했을 것입니다 global_scope.



답변

짧은 대답 : 꼭 필요한 경우가 default_scope아니면 사용 하지 마십시오 . 명명 된 범위를 사용하는 것이 좋습니다. 그렇게 말하면 with_exclusive_scope필요한 경우 기본 범위를 재정의하는 데 사용할 수 있습니다.

자세한 내용 은 이 질문 을 보십시오 .


답변

레일즈 3에서 :

foos = Foo.unscoped.where(:baz => baz)


답변

에 정의 된 순서를 변경하기 만하면 메소드를default_scope 사용할 수 있습니다 .reorder

class Foo < ActiveRecord::Base
  default_scope order('created_at desc')
end

Foo.reorder('created_at asc')

다음 SQL을 실행합니다.

SELECT * FROM "foos" ORDER BY created_at asc


답변

때문에 4.1당신이 사용할 수있는 ActiveRecord::QueryMethods#unscope기본 범위를 싸울 :

class User < ActiveRecord::Base
  default_scope { where tester: false }
  scope :testers, -> { unscope(:where).where tester: true }
  scope :with_testers, -> { unscope(:where).where tester: [true, false] }
  # ...
end

그것은이다 현재 가능한 unscope같은 물건 : :where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having.

그러나 가능하면 사용을 피하십시오default_scope . 그것은 당신 자신의 이익을위한 것입니다.


답변

with_exclusive_scope메소드를 사용하여 기본 범위를 대체 할 수 있습니다 . 그래서:

foos = Foo.with_exclusive_scope { :conditions => ["baz = ?", baz] }

답변

Rails 3 default_scope는 Rails 2에서와 같이 재정의되지 않은 것으로 보입니다.

예 :

class Foo < ActiveRecord::Base
  belongs_to :bar
  default_scope :order=>"created_at desc"
end

class Bar < ActiveRecord::Base
  has_many :foos
end

> Bar.foos
  SELECT * from Foo where bar_id = 2 order by "created_at desc";
> Bar.unscoped.foos
  SELECT * from Foo;  (WRONG!  removes the "has" relationship)
> Bar.foos( :order=>"created_at asc" )  # trying to override ordering
  SELECT * from Foo where bar_id = 2 order by "created_at desc, created_at asc"

내 응용 프로그램에서 PostgreSQL을 사용하여 기본 범위 WINS의 순서입니다. 나는 모든 default_scopes를 제거하고 명시 적으로 모든 곳에서 코딩하고 있습니다.

함정 레일 3!


답변

Rails 3 이상에서는 범위가 지정되지 않고 병합 된 조합을 사용할 수 있습니다.

# model User has a default scope
query = User.where(email: "foo@example.com")

# get rid of default scope and then merge the conditions
query = query.unscoped.merge(query)