developer tip

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

optionbox 2020. 8. 25. 07:54
반응형

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를 통해 주문하는 것보다 훨씬 느리고 메모리를 많이 사용합니다.

If you are doing something where adding a default order is cumbersome for some reason or you want to override your default in certain cases, it is trivial to specify it in the fetching action itself:

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

If you are using Rails 2.3 and want to use the same default ordering for all collections of this object you can use default_scope to order your collection.

class Student < ActiveRecord::Base
  belongs_to :class

  default_scope :order => 'name'

end

Then if you call

@students = @class.students

They will be ordered as per your default_scope. TBH in a very general sense ordering is the only really good use of default scopes.


You can use ActiveRecord's find method to get your objects and sort them too.

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

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


And if you need to pass some additional arguments like dependent: :destroy or whatever, you should append the ones after a lambda, like this:

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

참고URL : https://stackoverflow.com/questions/738971/how-do-i-automatically-sort-a-has-many-relationship-in-rails

반응형