[ruby-on-rails] 레일 모델의 기본 정렬 순서?
모델에서 기본 정렬 순서를 지정하고 싶습니다.
그래서 내가 .where()
지정하지 않고 할 때 .order()
기본 정렬을 사용합니다. 그러나를 지정 .order()
하면 기본값이 무시됩니다.
답변
default_scope
이것은 Rails 4+에서 작동합니다 :
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
Rails 2.3, 3의 경우 다음이 필요합니다.
default_scope order('created_at DESC')
Rails 2.x의 경우 :
default_scope :order => 'created_at DESC'
created_at
기본 정렬을 수행 할 필드는 어디 입니까?
참고 : ASC 는 오름차순에 사용되는 코드이고 DESC 는 내림차순에 사용됩니다 ( desc
, NOT dsc
!).
scope
익숙해지면 다음을 사용할 수도 있습니다 scope
.
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
Rails 2의 경우 필요합니다 named_scope
.
:published
scope Book.published
대신을
제공합니다 Book.find(:published => true)
.
Rails 3부터는 메소드를 서로 마침표로 연결하여 ‘체인’할 수 있으므로 위의 범위에서 이제 사용할 수 있습니다 Book.published.confirmed
.
이 방법을 사용하면 실제 결과가 필요할 때까지 (실제 평가) 쿼리가 실제로 실행되지 않으므로 7 개의 스코프는 서로 연결될 수 있지만 7 개의 개별 쿼리를 실행하여 성능 문제를 피하기 위해 1 개의 실제 데이터베이스 쿼리 만 생성 할 수 있습니다.
날짜 또는 user_id와 같은 전달 된 매개 변수를 사용할 수 있습니다 (런타임시 변경 될 수 있으므로 다음과 같이 람다로 ‘지연 한 평가’가 필요함).
scope :recent_books, lambda
{ |since_when| where("created_at >= ?", since_when) }
# Note the `where` is making use of AREL syntax added in Rails 3.
마지막으로 다음을 사용하여 기본 범위를 비활성화 할 수 있습니다.
Book.with_exclusive_scope { find(:all) }
또는 더 나은 :
Book.unscoped.all
그러면 필터 (조건) 또는 정렬 (순서 순)이 비활성화됩니다.
첫 번째 버전은 Rails2 +에서 작동하는 반면 두 번째 (범위가 지정되지 않은)는 Rails3 + 전용입니다.
그래서
… 당신이 생각하고 있다면, 흠, 이것들은 방법과 같습니다 … 그렇습니다. 이것이 바로 이러한 범위입니다!
그것들은 마치 def self.method_name ...code... end
루비와 마찬가지로 항상 당신을 위해 일을 더 쉽게 할 수있는 좋은 작은 구문 단축키 (또는 ‘설탕’)입니다!
실제로 이들은 1 세트의 ‘모든’레코드에서 작동하므로 클래스 레벨 방법입니다.
그러나 형식이 변경 되고 레일 4에서는 호출 가능한 객체를 전달하지 않고 #scope를 사용할 때 사용 중단 경고가 표시됩니다. 예를 들어 scope : red, where (color : ‘red’)를로 변경해야합니다 scope :red, -> { where(color: 'red') }
.
부수적으로, 잘못 사용하면 기본 _scope가 잘못 사용되거나 악용 될 수 있습니다.
이것은이 같은 활동을 위해 사용됩니다 경우에 대해 주로 where
의 제한 (필터링)을 기본 선택 (A 나쁜 생각 만 주문 결과를 사용하기보다는 기본에 대한).
들어 where
선택, 그냥 일반라는 이름의 범위를 사용합니다. 그리고 예를 들어, 쿼리에 그 범위를 추가 할 Book.all.published
경우 published
명명 된 범위입니다.
결론적으로, 스코프는 정말 훌륭하고 ‘팻 모델 씬 컨트롤러’DRYer 접근법을 위해 모델로 물건을 밀어 넣는 데 도움이됩니다.
답변
위의 Michael의 훌륭한 답변에 대한 빠른 업데이트.
Rails 4.0 이상에서는 다음과 같은 블록으로 정렬해야합니다.
class Book < ActiveRecord::Base
default_scope { order('created_at DESC') }
end
order 문은 중괄호로 표시된 블록에 배치됩니다.
역동적 인 것을 전달하기가 너무 쉽기 때문에 (현재 시간과 같이) 변경했습니다. 런타임에 블록이 평가되므로 문제가 해결됩니다. 블록을 사용하지 않으면이 오류가 발생합니다.
블록없이 #default_scope 호출에 대한 지원이 제거되었습니다. 예를 들어 대신을
default_scope where(color: 'red')
사용하십시오default_scope { where(color: 'red') }
. 또는 self.default_scope를 다시 정의 할 수도 있습니다.
으로 @Dan는 아래 자신의 코멘트에 언급,이 같은 더 rubyish 구문을 수행 할 수 있습니다
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
또는 여러 열이있는 경우 :
class Book < ActiveRecord::Base
default_scope { order({begin_date: :desc}, :name) }
end
감사합니다 @ Dan !
답변
default_scope를 사용하여 기본 정렬 순서를 구현할 수 있습니다.
http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html