Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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 4 按排序的rails有很多关系_Ruby On Rails 4_Has Many_Database Relations - Fatal编程技术网

Ruby on rails 4 按排序的rails有很多关系

Ruby on rails 4 按排序的rails有很多关系,ruby-on-rails-4,has-many,database-relations,Ruby On Rails 4,Has Many,Database Relations,我试着根据每个人的评论数量来安排我的音乐会。这场音乐会有很多评论。我试过这么做 <% @concerts = Concert.all %> <% @concerts.order(reviews.size).each do |concert| %> - - - <% end %> - - - 但是我得到了这个错误 未定义的方法“审查” ActiveRecord::Relation::ActiveRecord_Relation_Concert:0

我试着根据每个人的评论数量来安排我的音乐会。这场音乐会有很多评论。我试过这么做

<% @concerts = Concert.all %>
<% @concerts.order(reviews.size).each do |concert| %>
  -
  -
  -
<% end %>

-
-
-
但是我得到了这个错误

未定义的方法“审查” ActiveRecord::Relation::ActiveRecord_Relation_Concert:0xb5540398>


有没有建议我如何参考每场音乐会的评论数量?

不是最好的,但最简单的解决方案是

@concerts = Concert.all.includes(:reviews).sort_by{|concert| concert.reviews.size}.reverse

另一个答案的替代方案最终会给出相同的结果集,但会产生稍微不同的副作用:

Concert.select("concerts.*, count(reviews.id) review_count")
       .joins("LEFT JOIN reviews ON concerts.id = reviews.concert_id")
       .group("concerts.id")
       .order("review_count")
主要区别在于,这个查询在使用之前不会立即执行;您将收到一个活动记录关系,就像您通常使用任何活动记录查询方法时一样,这意味着您可以进一步细化或添加查询(假设地说)

另一个不同之处是,此查询不需要立即加载
评论。根据您的需要,如果您不需要来自相关评论的任何信息,此查询将运行得更快

就时间/性能而言,使用一个包含50场音乐会和43867篇评论(索引存在于FK上)的数据库,两个版本似乎在几乎相同的时间内执行(急切加载)。下面是我的基准测试结果表(所有结果以秒为单位):

正如您所看到的,使用即时加载的两个查询之间没有显著差异,使用上面的我的查询而不使用即时加载的一个主要差异。显然,确切的结果对你来说是不同的,但这应该让你了解相对的差异

旁注: 从您在问题中发布的内容来看,您似乎想要在ERB视图中编写此查询。我强烈建议将此查询移动到
Concert
模型中的一个方法,并从控制器中该方法的返回创建一个实例变量,然后视图可以使用它。这样你就可以把所有的东西都分开

编辑 为了说明我的建议,我将把查询放在
Concert
模型的类方法中,如下所示:

def self.ordered_by_reviews
    return select("concerts.*, count(reviews.id) review_count")
          .joins("LEFT JOIN reviews ON concerts.id = reviews.concert_id")
          .group("concerts.id")
          .order("review_count")
end
您可以从您的控制器调用该功能(与哪个控制器无关):

然后,您可以根据需要使用
@concerts
,并可以删除任何类似
@concerts=Concert.all
等内容

或者,您也可以使用作用域来做同样的事情(我相信这会被视为更Rails-y):

classconcert{select(“concerts.*,count(reviews.id)review_count”).joins(“LEFT JOIN reviews ON concerts.id=reviews.concert_id”).group(“concerts.id”).order(“review_count”)}
... 其他同学

未测试,但这应该有效:Concert.joins(:reviews.group('reviews.Concert_id')。order('COUNT(reviews.id)')不起作用:错误:列“concerts.id”必须出现在group BY子句中或用于聚合函数行1:选择“concerts”。*从“concerts”中选择“internal JOIN”reviews ON…因此这至少适用于大多数评论,从大到小怎么样?谢谢你。我实际上是在ERB视图中使用它进行审查。我将研究如何将其作为音乐会的一种方法。它需要进入音乐会控制器,对吗?我还应该注意到,我只想在10场音乐会上这样做,但这并不重要,因为在展示前10场音乐会之前,我必须组织好所有的音乐会suppose@user2739431好的,您应该不会在添加类似
.limit(10)
,或一些
。where
子句参数时遇到任何问题,但是,您打算将它们限制在~10。将发生的事情是,整个事情将被排序,然后根据您指定的
。where
limit
参数进行过滤。至于你的问题需要进入音乐会控制员,不是100%确定你的意思,你能详细说明吗?我将编辑这个问题,并添加一个示例,说明我的意思是查询应该去哪里,如果这是您的意思的话。
def self.ordered_by_reviews
    return select("concerts.*, count(reviews.id) review_count")
          .joins("LEFT JOIN reviews ON concerts.id = reviews.concert_id")
          .group("concerts.id")
          .order("review_count")
end
... other controller code:
@concerts = Concert.ordered_by_reviews
... and so on
class Concert < ActiveRecord::Base
    scope :ordered_by_review, -> { select("concerts.*, count(reviews.id) review_count").joins("LEFT JOIN reviews ON concerts.id = reviews.concert_id").group("concerts.id").order("review_count") }
    ... rest of class