【问题标题】:Rails: Method for joining if a user has liked a set of songsRails:如果用户喜欢一组歌曲,则加入的方法
【发布时间】:2011-11-15 02:53:39
【问题描述】:

我有以下型号:

  • 用户
  • 播放列表
  • 歌曲喜欢
  • 歌曲
  • ...

当我查询一个播放列表的所有歌曲时,我会返回一个歌曲对象数组。找出用户“喜欢”了哪些歌曲的最有效方法是什么?点赞数存储在 SongLike 模型中:

class SongLike < ActiveRecord::Base
  belongs_to :user
  belongs_to :song, :counter_cache => "likes_count"
end

...这是歌曲模型:

class Song < ActiveRecord::Base
  has_and_belongs_to_many :playlists
  has_many :featured_songs
  has_many :song_likes
  has_many :users, :through => :song_likes
  ...
end

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    利用您的 song_likes 关联以及内存中的歌曲,而不是多次查询数据库:

    # user.rb
    def songs_liked_from(subset)
      like_ids = self.song_likes.where(:song_id => subset.map(&:id)).select(:song_id).map(&:song_id)
      subset.select{|s| liked_ids.include?(s.id) }
    end
    

    【讨论】:

    • 要使like_ids.include? 调用更高效,您还可以通过以下方式最小化like_ids 的大小:like_ids = self.song_likes.where(:song_id =&gt; subset.map(&amp;:id)).select(:song_id).map(&amp;:song_id)。如果用户有数百个喜欢,其中一些不在子集中,这将影响性能。
    • 一个用户可能有成千上万的赞,你能用优化更新答案吗?如果用户可能有 2000+ 个赞,它是否可用?谢谢你:)。
    【解决方案2】:

    您可以在一起查找的 user_id 和 song_id 上放置一个索引,如果这适用于您的系统,则可以使其唯一。

      def songs_user_liked
        user_liked_songs = []
        songs.each do |song|
          song_like = SongLike.find_by_user_id_and_song_id(#,song)
          if song_like.song_like_count > 0
            user_liked_songs << song
          end
        end
        user_liked_songs
      end
    

    【讨论】:

      猜你喜欢
      • 2020-11-04
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 2014-09-21
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多