首页 > 解决方案 > 如何在 Rails 类模型范围内编写格式为 'SELECT ... FROM ... WHERE ... IN ( SELECT ... )' 的 SQL?

问题描述

我如何编写 SQL

SELECT * 
FROM tableA 
WHERE tableA.col1 IN (
  SELECT tableB.col2 
  FROM tableB
)

在 Rails 模型范围内?

目前,我在 ruby​​ 模型文件中有一个这样的 SQL 作为类方法:

class Book
  def self.select_list_for_current_project_fund_schemes_sponsor_name
    Books.connection.select_all('
      SELECT book.name, book.name 
      FROM BOOK b
      WHERE b.b_pk IN (
        SELECT s.b_fk
        FROM STORE s
      )
    ').rows
  end
end

它可以工作,并产生我想要的输出:

Book.select_list_for_current_project_fund_schemes_sponsor_name
=> [[book_name1, book_name1], [book_name2, book_name2], [book_name3, book_name3]...]

但我想在范围内编写它,以便与其他代码保持一致。

如何在类模型范围内使用 ActiveRecord 'where' 方法编写上述 SQL?

我想在类的模型文件中有这样的东西:

class Book
  scope :books_in_store_that_exist, -> { where(magic_sql_wrapped_in_ruby_here) }

  # more code here...
end

注意:我没有 Store 模型,我只有 Book 模型。

换句话说,我希望能够通过编写来实现相同的输出

Book.books_in_store_that_exist.select(:name).map {|b| [b.name, b.name]}
=> [[book_name1, book_name1], [book_name2, book_name2], [book_name3, book_name3]...]

标签: sqlruby-on-railsrubyactiverecord

解决方案


在这种情况下,您只需要添加一个内部连接

class Book
  scope :books_in_store_that_exist, -> { joins("INNER JOIN stores ON books.b_pk = stores.b_fk") }
end

现在您可以使用它来链接它。

Book.books_in_store_that_exist.select(:name).map { |b| [b.name, b.name] }
#=> [[book_name1, book_name1], [book_name2, book_name2], [book_name3, book_name3]...]

推荐阅读