ruby-on-rails - Rails 4 - 加入 AND 子句

标签 ruby-on-rails postgresql join

下面的查询会根据用户的下一个问题状态为我提供该问题。它获取该特定部分的所有问题,然后作用域对属于该用户的状态执行 LEFT JOIN

我的问题是,这似乎不是一种非常 Railsy 的方法 - 是否有更好的方法来过滤我的表而不是这种笨拙的 AND.to_s业务。我的问题是,显然,如果有任何用户回答了该问题,则左联接将填满该用户的答案,而我要求它为空。

本质上查询有效但很丑,我不知道这是否是最有效的方法!

scope :next_for_user, lambda { |user|
    joins("LEFT JOIN user_question_statuses ON user_question_statuses.question_id = questions.id AND user_question_statuses.user_id = ", user.id.to_s).
    reorder("user_question_statuses.answered ASC NULLS FIRST").
    order("user_question_statuses.updated_at ASC NULLS FIRST").
    limit(1)
  }

编辑:

我意识到这种方法特别容易受到 SQL 注入(inject)的攻击,所以我将查询中的主线替换为:

joins(sanitize_sql_array(["LEFT JOIN user_question_statuses ON user_question_statuses.question_id = questions.id AND user_question_statuses.user_id = %d", user.id]))

这似乎有效并强制输入仅为整数。

编辑 2:

我的另一个选择是使用 find_each 然后使用用户 first_or_create 为当前用户的特定问题部分创建空问题状态。这可能发生在他们寻找问题之前需要他们的时候。这将允许我从问题到这些状态做一个 RIGHT JOIN,知道它们存在,但如果第一种方法是高效和安全的(并且尽可能 Railsy),那么没有理由改变它。

编辑 3:

我以这种方式构造此查询是因为 - 从 has_many questionssection 模型 - 我想找到下一个 应该传递给用户的问题

要找到它,我需要将所有 user_question_statuses 加入到所有 section 模型的问题中。唯一可以做到这一点的方法是在 question.id 上。但是,对于不同的用户,有许多具有该问题 ID 的 user_question_statuses。因此,在加入时,我需要 AND 子句在加入发生之前将 user_question_statuses 过滤为仅来自该 user 的那些。很明显,用户每个问题只有一个状态。

我使用 LEFT JOIN 这样如果状态尚不存在(它们仅在用户第一次尝试问题后创建),仍然有状态为 NULL 无处不在,以便他们创建一行,然后从该行移动到顶部(因此 NULLS FIRST)并可能服务器到 user

这一切可能都非常不清楚!

最佳答案

您所做的是跳过 Active Record 提供的 ORM 层并自行构建查询。您的感觉是正确的,因为这种方法有很多限制并且不太适合 Rails 遵循的 MVC 模型。我建议通读 Active Record Query Interface获得以 rails/oop 方式进行操作的概念

关于ruby-on-rails - Rails 4 - 加入 AND 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28384137/

相关文章:

sql - 使用一个 JOIN 次数越多,列越多

PHP、SQL - 复杂的查询需要 40 多秒

php - 在 PHP 中合并两个数组

MySQL:用户 'root@localhost' 的访问被拒绝(使用密码:NO)

javascript - Ruby on Rails - 单击按钮时将从 Javascript 下拉列表中选择的项目传递到 Rails Controller

ruby-on-rails - Rails 4链接以使用Elasticsearch搜索

sql - 如何限制列中的 JSON/JSONB 值完全不同?

ruby-on-rails - 在 Ruby on Rails 中播种

python - 处理 SQL Alchemy session 。

postgresql - AWS RDS Proxy 可以直接与读复制实例配对吗?