【问题标题】:ActiveRecord get all model records plus those matching some criteriaActiveRecord 获取所有模型记录以及匹配某些条件的记录
【发布时间】:2017-11-22 12:44:32
【问题描述】:

我正在尝试创建一组复选框标签,以便用户可以看到他有多少(已订阅),以及哪些没有。

我的模型是 User、Category 和 Preferences,它们通过两个第一个模型之间的关系处理 has_many:

class User < ApplicationRecord
  has_many :preferences
  has_many :categories, through: :preferences
end

class Category < ApplicationRecord
  has_many :preferences
  has_many :users, through: :preferences
end

class Preference < ApplicationRecord
  belongs_to :user
  belongs_to :category
end

我们的目标是让所有类别都存在,并能够以一种额外的方式检查用户是否拥有此类类别,这样我就可以使用有效的 CSS 规则并显示它们与用户没有的类别不同.

我尝试获取所有类别名称,以及与用户对应的所有类别名称,并将它们作为一个数组加入,其中包含多个 2 元素数组,我得到如下内容:

[
  ["coffee",         "coffee"],
  ["coworking",      "food"],
  ["event",          "pub"],
  ["food",           "restaurant"],
  ["landmark",       "shop"],
  ["nightlife",      "vacation"],
  ["pub",            nil],
  ["restaurant",     nil],
  ["shop",           nil],
  ["transportation", nil],
  ["vacation",       nil]
]

如果我能让它们在名称上匹配,这种方式会很好,因为每个数组的名称永远不会重复,可能像:

[
  ["coffee",         "coffee"],
  ["coworking",      nil],
  ["event",          nil],
  ["food",           "food"],
  ["landmark",       nil],
  ["nightlife",      nil],
  ["pub",            "pub"],
  ["restaurant",     "restaurant"],
  ["shop",           "shop"],
  ["transportation", nil],
  ["vacation",       "vacation"],
]

所以我可以在数组的最后一个(第二个)元素中查看其中哪些是 nil 并且不打印检查元素的 CSS 规则。

但似乎我需要在 ActiveRecord 查询之外进行。

是否存在通过使用 ActiveRecord 获得所需结果的任何方法,或者我必须手动处理它,或者更改架构?

【问题讨论】:

  • 我不是 SQL 专家,但这听起来像是 left_outer_joins sql 查询,不是吗?

标签: ruby-on-rails ruby postgresql activerecord


【解决方案1】:

您只需几个步骤即可完成。

首先获取所有类别

all_categories = Category.all

然后获取用户类别(我假设您已经有代码为请求定义current_user

@user_categories = current_user.categories

那么你就可以找到两者的区别了:

@non_user_categories = all_categories - @user_categories

@user_categoriesall_categories 严格来说不是数组 - 它们是 ActiveRecord::Relation 对象。但是您仍然可以使用数组减法来找出差异。请注意,@non_user_categories 一个实际的数组。


您可以采取另一种方式来避免加载过多的记录,但对于小数据集而言,性能提升将是无关紧要的。

@user_categories = current_user.categories

@non_user_categories = Category.joins(:preferences).where.not(
  "preferences.user_id = ?",
  current_user.id
)

【讨论】:

  • 我试过@user_categories = Category.joins(:preferences).where(preferences: { user_id: id })来获取user_categories,我不知道为什么但是使用where.not它不显示非用户类别,只是一个空的查询结果。跨度>
猜你喜欢
  • 2015-04-08
  • 2016-09-26
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 2022-01-04
  • 1970-01-01
  • 2012-07-31
相关资源
最近更新 更多