Ruby on Rails:选择用户未与之交互的模型

时间:2016-05-10 04:08:48

标签: ruby-on-rails ruby ruby-on-rails-4

我是Ruby on Rails的新手,但是我花了一整天的时间尝试了我在网上找到的所有不同的解决方案,但我还是什么都没有。

我有三种模式:用户,曲目和Feed。

用户非常自我解释 曲目是用户可以上传的歌曲, 和Feed是用户留下的反馈曲目

我有:

class User < ActiveRecord::Base
  has_many :tracks, dependent: :destroy
  has_many :feeds

class Track < ActiveRecord::Base
  belongs_to :user
  has_many :feeds, dependent: :destroy

class Feed < ActiveRecord::Base
  belongs_to :track
  has_one :user

我需要选择用户尚未留下反馈的曲目。我试过了:

Track.joins(:feeds).where("feeds.user_id != #{current_user.id}").where("tracks.user_id != #{current_user.id}")

但这并没有产生任何结果。

有人帮忙吗?

如有需要,请提供额外信息:

User.column_names()
 => ["id", "email", "encrypted_password", "reset_password_token", "reset_password_sent_at", "remember_created_at", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip", "created_at", "updated_at", "genre", "name", "genre_id", "slug"]

Track.column_names()
 => ["id", "title", "link", "user_id", "created_at", "updated_at", "slug", "average_feed", "feed_avaliable", "feed_level", "pref_genre", "last_feed"] 

Feed.column_names()
 => ["id", "feedback", "user_id", "track_id", "created_at", "updated_at", "overall", "feed_for"] 

class PageController < ApplicationController

  def feed
    @track = Track.joins(:feeds).where("feeds.user_id != #{current_user.id}").where("tracks.feed_avaliable > '0'").where("tracks.user_id != #{current_user.id}").reorder(feed_level: :asc, last_feed: :desc, created_at: :asc).first()
    @feed = current_user.feeds.build if user_signed_in?
  end

2 个答案:

答案 0 :(得分:0)

首先使用Feed模型更正User模型关系,如:

class Feed < ActiveRecord::Base
  belongs_to :track
  belongs_to :user

获取用户没有留下反馈的tracks的一种方法可能是:

track_ids = current_user.feeds.pluck(:track_id).uniq
@tracks = Track.where("id NOT IN (?)", track_ids)

您将获得用户未收到反馈的曲目。

答案 1 :(得分:-1)

首先,正如穆罕默德正确指出的那样,Feed应该belongs_to User,而不是has_one

class Feed < ActiveRecord::Base
  belongs_to :track
  belongs_to :user
end

此示例使用Rails 4中引入的where.not功能。

Track.where.not(id: current_user.feeds.select(:track_id))

假设您的用户的ID为42。这应该生成

SELECT tracks.* FROM tracks WHERE tracks.id NOT IN (
  SELECT feeds.track_id FROM feeds WHERE feeds.user_id = 42 
)

您通常希望不惜一切代价避免SQL查询中的字符串插值。有几种方法可以安全地完成,但在这种情况下,您可以使用ruby界面。

这比pluck id更可取,因为这需要两次往返DB,而像这样的子查询只需要一个。但是,与往常一样,您应该对查询进行概要分析,以确保它们快速并检查所需的索引。