【问题标题】:Rails 4 + ActiveRecord: How to exclude some records from the search?Rails 4 + ActiveRecord:如何从搜索中排除一些记录?
【发布时间】:2015-11-10 20:58:20
【问题描述】:

我有这些表:

  1. users - 经典的设计桌
  2. listings - 用户创建列表
  3. listings_exclude_users - 2 列:user_idlisting_id

用户.rb

class User 
  has_many :listings
end 

listing.rb

class Listing
  belongs_to :user
  has_many :listing_excluded_users
end

listing_excluded_user.rb

class ListingExcludedUser
  belongs_to :user
  belongs_to :listing
end

我标记了一些不应该显示相应列表的用户,并且此信息保存在listings_exclude_users

现在我想运行一个可以获取所有列表的查询,但如果在特定列表的listings_exclude_users 表中的用户登录,则不要获取此列表。

我可以在视图中执行此操作,但我更喜欢 ActiveRecord 方式。 我试过了

@listings = Listing.joins(:listing_excluded_users).where("listings.status='0' AND (listing_excluded_users.user_id != '#{current_user.id}')")

但是这个查询没有返回任何东西(空@listings)。

提前感谢您的建议。

【问题讨论】:

  • 您使用的是什么数据库? mysql? postgres?
  • 永远不要在 SQL 片段中执行类似“...#{varname}”的操作。也许这次你是安全的,但有一天你会得到 SQL 注入。您应该学习如何在 SQL 语句中使用参数。
  • 在这种情况下,#{current_user.id} 是安全的,因为它可能不是用户输入,但是,是的,使用参数的好习惯,因为我已经重写了下面的查询。

标签: ruby-on-rails ruby activerecord has-many


【解决方案1】:

这可以通过两个查询轻松完成。如果您需要一个查询,您可能需要一个子查询。

2 个查询:

user_ids_to_exclude = ListingExcludedUser.where.not(user_id: current_user.id).pluck(:user_id)
@listings = Listing.where.not(user_id: user_ids_to_exclude)

子查询

@listings = Listing.where.not(user_id: ListingExcludedUser.where.not(user_id: current_user.id).select(:user_id))

注意:where.not 是 Rails 4 惯用语。

【讨论】:

  • 谢谢Peter,您的回答。但是,此查询与 OP 中的查询有何不同?无论如何,问题是输出是一个空数组。如果我在 DB 表中有 10 个列表,并且我决定不想让第一个对用户可见,那么其余 9 个应该显示在那里。
  • 键是 '' 而不是 '!='。这就是你在 sql 中不这样做的方式。
  • 我很确定问题在于您正在执行的连接类型。通过进行内部连接,您将排除不在排除表中的行,这与您想要的相反!请参阅上面的编辑以使用 OUTER JOIN。
  • 是的,内部连接是错误的。外部连接是不够的,因为一个列表可能已被两个用户排除,其中一个是当前用户。然后外连接仍然返回它,因为有另一个用户不是当前用户。在 SQL 逻辑中,非条件不是那么容易。
  • OP 没有提到需要检查多个用户,@user984621 - 您能否澄清您的问题是否需要在排除查询中包含多个用户?如果是这样,请更新上面的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 2014-05-02
  • 2017-08-07
  • 1970-01-01
相关资源
最近更新 更多