Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在Rails中自动对多个关系排序?_Ruby On Rails - Fatal编程技术网

Ruby on rails 如何在Rails中自动对多个关系排序?

Ruby on rails 如何在Rails中自动对多个关系排序?,ruby-on-rails,Ruby On Rails,这似乎是一个非常简单的问题,但我还没有看到答案 在rails中,如果您有: class Article < ActiveRecord::Base has_many :comments end class Comments < ActiveRecord::Base belongs_to :article end 如果您需要经常引用命名范围,甚至人们也会这样做: @article.comments(:order=>"created_at DESC") @art

这似乎是一个非常简单的问题,但我还没有看到答案

在rails中,如果您有:

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 }
class Article < ActiveRecord::Base 
  has_many :comments, -> { order(created_at: :desc) }, dependent: :destroy
end
@article.comments.sort{| x,y | x.created_at y.created_at}

但有些事情告诉我应该更简单。我遗漏了什么?

您可以使用ActiveRecord的查找方法获取对象并对其进行排序

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

您可以使用
has\u many
本身上的选项指定裸集合的排序顺序:

class Article < ActiveRecord::Base 
  has_many :comments, :order => 'created_at DESC'
end 
class Comment < ActiveRecord::Base 
  belongs_to :article 
end
使用ActiveRecord添加的订购方法收集此文件:

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

您的里程可能会有所不同:上述解决方案的性能特征将发生巨大变化,这取决于您首先获取数据的方式以及运行应用程序所使用的Ruby。

如果您使用Rails 2.3并希望对该对象的所有集合使用相同的默认排序,则可以使用默认范围进行排序你的收藏

class Student < ActiveRecord::Base
  belongs_to :class

  default_scope :order => 'name'

end

它们将按照您的默认范围进行订购。TBH在一个非常普遍的意义上,排序是默认作用域唯一真正好的用途。

对于Rails 4,您可以做:

class Article < ActiveRecord::Base 
  has_many :comments, -> { order(created_at: :desc) }
end 
class Comment < ActiveRecord::Base 
  belongs_to :article 
end
如果您始终希望以相同的顺序访问注释,无论上下文如何,您也可以通过
default\u scope
Comment
中执行此操作,如:

class Comment < ActiveRecord::Base 
  belongs_to :article 
  default_scope { order(created_at: :desc) }
end
正如Jim所提到的,在获取结果后,您也可以使用
sort\u by
,尽管在任何大小的结果集中,这将比通过SQL/ActiveRecord进行排序慢得多(并且占用大量内存)

如果由于某种原因,添加默认订单很麻烦,或者在某些情况下希望覆盖默认订单,那么在抓取操作本身中指定默认订单是很简单的:

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

如果您需要传递一些附加参数,如
dependent::destroy
或其他什么,您应该在lambda后面追加这些参数,如下所示:

@article.comments(:order=>"created_at DESC")
@article.comments.sort { |x,y| x.created_at <=> y.created_at }
class Article < ActiveRecord::Base 
  has_many :comments, -> { order(created_at: :desc) }, dependent: :destroy
end
类文章{order(created_at::desc)},dependent::destroy
结束

或简写方法@article.comments.all(:order=>'created_at DESC')谢谢,“all”可能是最简单的。好东西!在Rails 4中,order选项已被删除。使用lambda
->{order(created_at::desc)}
。请参阅:rails 4不推荐使用此方法,请参阅小心,您使用的是意外方法:@article.comments(reload=false)用于强制缓存未命中(强制重新加载关系)。如果您提供一个散列,它与@article.comments(true)相同。不要忘记使用.all(:order=>“…”)。我的腿已经断了好几次了。从Rails 4开始,这是不符合要求的。请参阅此解决方案以了解正确的Rails 4语法:在抓取操作本身的何处可以指定它?我是否重写模型中的方法?@Wit-您可以向方法链添加
.order()
,如上一个示例所示。这就是你要问的吗?对不起。我记不起我想达到什么目的了。通过多态性的例子在这里非常有用!警告:如果您在rails 6中执行lambda,您将丢失的隐式逆函数,因此如果您尝试在has_many中使用新记录保存记录,它将不会像没有lambda时那样首先自动保存子记录。
class Article < ActiveRecord::Base 
  has_many :comments, -> { order(created_at: :desc) }, dependent: :destroy
end