【问题标题】:how to sort ruby array by model action?如何通过模型操作对 ruby​​ 数组进行排序?
【发布时间】:2016-02-11 07:16:21
【问题描述】:

我正在尝试制作一个基于社交网络的咖啡馆搜索服务项目,我想按其他用户给出的点数对咖啡馆数组进行排序。

class Cafe < ActiveRecord::Base

  belongs_to :user

  has_many :posts, dependent: :destroy
  has_many :tags, dependent: :destroy
  has_many :payments, dependent: :destroy
  has_many :payinfos, dependent: :destroy
  mount_uploader :image,CafeimageuploaderUploader
  mount_uploader :thumnail,CafeimageuploaderUploader

  geocoded_by :address
  after_validation :geocode
  def avg
    total = 0
    posts.each do |c|
      total += c.score
    end
    if posts.count == 0
        0
    else
      total.to_f / posts.count
    end
  end
end

这是 Cafe 模型,'avg' 是用户给出的平均分。

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|

      t.string :content              , null: false, default: ""
      t.string :image
      t.string :address              , null: false, default: "위치정보 없음"
      t.string :hashstr
      t.datetime :writtentime
      t.integer :user_id
      t.integer :cafe_id             , null: false, default: 0
      t.integer :score, default:0
      t.timestamps null: false
    end
  end
end

这里是帖子专栏。

我想做的是通过这个 avg 动作对新的 Cafe 数组进行排序。(它被称为模型动作,对吗??)

给我一​​些建议,谢谢。

【问题讨论】:

  • 旁注: posts.each { |c| total += c.score } 效率很低。改用posts.sum(&amp;:score) 将计算移至db层。

标签: ruby-on-rails arrays ruby sorting


【解决方案1】:

我会在 cafe 模型中添加一个属性 average_score,并在 post 模型中添加一个 after_save 回调方法。如果一个帖子是安全的,你会获取咖啡馆的所有帖子(通过外键),计算平均分数并将其保存到咖啡馆,或者你触发咖啡馆模型的方法来做到这一点。这样您就可以轻松地对咖啡馆进行分类。

【讨论】:

    【解决方案2】:

    让我们使用db查询,效率更高。 (假设Cafe's table name is cafes

    Cafe.joins("LEFT OUTER JOIN (SELECT cafe_id, AVG(score) AS avg_score
                                 FROM posts
                                 GROUP BY cafe_id
                                ) AS temp
                ON cafes.id = temp.cafe_id
              ").order('temp.avg_score DESC NULLS LAST')
    

    理想情况下,我们首先计算临时表中的平均分数,然后通过cafe_idCafe 连接。之后,我们可以轻松地将orderavg_score 一起使用。 因为我们用的是LEFT OUTER JOIN,所以没有帖子的cafeavg_score会是NULL,所以我们用NULLS LAST来保证cafe会在最后。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多