简体   繁体   English

如何通过模型动作对红宝石数组进行排序?

[英]how to sort ruby array by model action?

I'm trying to make a project like cafe search service based on social network, and I want to sort Cafe array by points which other users gave. 我正在尝试创建一个基于社交网络的咖啡馆搜索服务之类的项目,并且我想按其他用户给出的分数对Cafe数组进行排序。

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

this is Cafe model, 'avg' is point average that users gave. 这是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

Here's post columns. 这是帖子专栏。

What I want to do is sort new Cafe array by this avg action.(is it called model action, right??) 我想做的是通过这个avg动作对新的Cafe数组进行排序。(它称为模型动作,对吗?)

give me some advice, thank you. 给我一些建议,谢谢。

I would add an attribute average_score to cafe model and a after_save callback method to post model. 我将向咖啡馆模型添加属性average_score并向模型添加after_save回调方法。 If a post will be safed you take all posts of a cafe (by the foreign key), calculate the average score and save it to the cafe or you trigger a method of the cafe model to do that. 如果可以确保张贴安全,则可以使用外键获取咖啡馆的所有帖子,计算平均分数并将其保存到咖啡馆,或者触发咖啡馆模型的方法来做到这一点。 So you can sort your cafes easily. 这样您就可以轻松对咖啡馆进行分类。

Let use db query, it is more efficient. 让我们使用db查询,它效率更高。 (assume Cafe's table name is cafes ) (假设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')

Ideally, we calculate the average score in a temporary table first then join with Cafe via cafe_id . 理想情况下,我们首先在临时表中计算平均分数,然后通过cafe_idCafe cafe_id After that, we can easily use order with avg_score . 之后,我们可以通过avg_score轻松使用order Because we are using LEFT OUTER JOIN , the avg_score of cafe which doesn't have any post will be NULL , so we use NULLS LAST to ensure that cafe will be in the end. 因为我们使用的是LEFT OUTER JOIN ,所以没有任何帖子的cafeavg_score将为NULL ,因此我们使用NULLS LAST来确保cafe会在最后。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM