[ruby-on-rails] Rails에서 has_many 관계를 자동으로 정렬하려면 어떻게해야합니까?

이것은 정말 간단한 질문처럼 보이지만 어디에서도 대답을 보지 못했습니다.

레일에 다음이있는 경우 :

class Article < ActiveRecord::Base
  has_many :comments
end
class Comments < ActiveRecord::Base
  belongs_to :article
end

다음과 같이 주석을 주문할 수없는 이유는 무엇입니까?

@article.comments(:order=>"created_at DESC")

명명 된 범위는 많은 참조가 필요하고 사람들도 다음과 같은 작업을 수행하는 경우에 작동합니다.

@article.comments.sort { |x,y| x.created_at <=> y.created_at }

그러나 뭔가 더 간단해야한다고 말해줍니다. 내가 무엇을 놓치고 있습니까?



답변

has_many자체 옵션을 사용하여 베어 컬렉션의 정렬 순서를 지정할 수 있습니다 .

class Article < ActiveRecord::Base
  has_many :comments, :order => 'created_at DESC'
end
class Comment < ActiveRecord::Base
  belongs_to :article
end

또는 데이터베이스가 아닌 간단한 정렬 방법을 원하면 sort_by를 사용 하십시오 .

article.comments.sort_by &:created_at

ActiveRecord가 추가 한 주문 방법으로이를 수집 :

article.comments.find(:all, :order => 'created_at DESC')
article.comments.all(:order => 'created_at DESC')

마일리지는 다를 수 있습니다. 위 솔루션의 성능 특성은 처음에 데이터를 가져 오는 방법과 앱을 실행하는 데 사용하는 Ruby에 따라 크게 달라집니다.


답변

Rails 4에서는 다음을 수행합니다.

class Article < ActiveRecord::Base
  has_many :comments, -> { order(created_at: :desc) }
end
class Comment < ActiveRecord::Base
  belongs_to :article
end

A에 대한 has_many :through관계 인수 순서는 (은 두 번째 수있다) 중요한 :

class Article
  has_many :comments, -> { order('postables.sort' :desc) },
           :through => :postable
end

당신은 항상 어떤 상황을 중요한 순서대로 액세스 의견을 원하지 않을 경우 당신은 또한을 통해이 작업을 수행 할 수 있습니다 default_scope내에서 Comment같은 :

class Comment < ActiveRecord::Base
  belongs_to :article
  default_scope { order(created_at: :desc) }
end

그러나 이것은 이 질문에서 논의 된 이유 때문에 문제가 될 수 있습니다 .

Rails 4 이전 order에는 다음과 같이 관계에 대한 키로 지정할 수있었습니다 .

class Article < ActiveRecord::Base
  has_many :comments, :order => 'created_at DESC'
end 

Jim이 언급했듯이 sort_by 결과를 가져온 후에도 있지만 크기의 결과 집합에서는 SQL / ActiveRecord를 통해 주문하는 것보다 훨씬 더 느리고 더 많은 메모리를 사용합니다.

어떤 이유로 기본 주문을 추가하는 것이 번거로운 작업을 수행하거나 특정 경우에 기본값을 재정의하려는 경우 가져 오기 작업 자체에서 지정하는 것은 간단합니다.

sorted = article.comments.order('created_at').all


답변

Rails 2.3을 사용 중이고이 객체의 모든 컬렉션에 대해 동일한 기본 순서를 사용하려면 default_scope를 사용하여 컬렉션을 정렬 할 수 있습니다.

class Student < ActiveRecord::Base
  belongs_to :class

  default_scope :order => 'name'

end

그럼 전화하면

@students = @class.students

기본 범위에 따라 주문됩니다. 매우 일반적인 의미에서 TBH는 기본 범위를 정말 잘 사용하는 유일한 방법입니다.


답변

ActiveRecord의 찾기 메서드를 사용하여 개체를 가져오고 정렬 할 수도 있습니다.

  @article.comments.find(:all, :order => "created_at DESC")

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html


답변

추가 인수를 전달해야하는 경우 다음과 같이 dependent: :destroy람다 뒤에 인수 를 추가해야합니다.

class Article < ActiveRecord::Base
  has_many :comments, -> { order(created_at: :desc) }, dependent: :destroy
end


답변