[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.

:publishedscope 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


답변