ruby-on-rails - 使用 Rails 4 对象将 PSQL 查询转换为工作

标签 ruby-on-rails ruby postgresql ruby-on-rails-4 psql

我有以下查询:

select * from email_contacts
where extract(month from created_at) = 4
and call_type = 'Membership NPS'
and email NOT IN
(
    select invite_email from nps_responses
    where extract(month from fs_created_at) = 4
    and invite_email is not null
)

然后我有一个 Rails 4 应用程序,它有两个对应的模型,EmailContactNpsResponse

如何将此查询转换为在 Rails 中的 Controller 方法中运行?我需要选择符合上述条件的所有 email_contacts

最佳答案

这可能不是完美的“Rails 方式”解决方案,但您可以使用 find_by_sql 来实现.使用 find_by_sql 仍会检索模型对象的实例化对象:

EmailContact.find_by_sql(your_sql_statement)

使用绑定(bind)变量

为了防止SQL注入(inject),你应该使用bind variables使用 find_by_sql 方法(绑定(bind)变量是由 ? 字符表示的占位符参数。find_by_sql 方法将在执行语句之前绑定(bind)参数值。 ) 从安全角度来看,强烈建议这样做。

这是在 find_by_sql 方法中使用带有绑定(bind)变量的 SQL 语句的示例:

EmailContact.find_by_sql("select * from email_contacts
          where extract(month from created_at) = ?
          and call_type = ?
          and email NOT IN
          (
              select invite_email from nps_responses
              where extract(month from fs_created_at) = ?
              and invite_email is not null
          )", 4, 'Membership NPS', 4)

注意事项:

  • find_by_sql 方法的第一个参数是作为字符串值的 SQL 语句。在这个特定的 SQL 字符串中,有三个 ? 字符作为占位符变量。
  • find_by_sql 中接下来的三个参数是要绑定(bind)到 SQL 语句中的 ? 字符的值。
  • 参数的顺序很重要 - 第一个绑定(bind)变量参数将绑定(bind)到第一个 ? 字符等。
  • 您可以拥有可变数量的绑定(bind)变量参数,只要 ? 的数量与绑定(bind)变量参数的数量相匹配。

为了更好地组织代码,您可以使用某种辅助方法来构造带有绑定(bind)变量的 SQL 语句。有点像这样:

def email_contacts_SQL
   sql = "select * from email_contacts
          where extract(month from created_at) = ?
          and call_type = ?
          and email NOT IN
          (
              select invite_email from nps_responses
              where extract(month from fs_created_at) = ?
              and invite_email is not null
          )"
end

然后将 find_by_sql 与您的辅助方法一起使用:

EmailContact.find_by_sql(email_contacts_SQL, 4, 'Membership NPS', 4)

official Rails API doc有更多关于如何使用 find_by_sql 的示例。

警告:如果您使用find_by_sql,您将失去ActiveRecord 提供的与数据库无关的转换。 find_by_sql 方法按原样执行 SQL 语句。

关于ruby-on-rails - 使用 Rails 4 对象将 PSQL 查询转换为工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23122366/

相关文章:

ruby-on-rails - Heroku asset_sync gem 没有上传到 s3

ruby-on-rails - 如何在 Rails/Ruby 中获取包含哈希值的完整 URL

postgresql - 以表名作为参数删除行的函数

jquery - 在 Rails 中运行 javascript

ruby-on-rails - 在 Ruby 中,当变量、方法或常量前面带有下划线时,这意味着什么?

html - url中的#/是什么意思?

linux - 如何检查我不知道名称的服务是否在 Ubuntu 上运行

javascript - 如何使用 javascript 将来自 postgres sql 查询的值分配给前端的字段

ruby-on-rails - 在 rails 中使用 RSpec 和 Capybara 时未定义的方法 `visit'

ruby-on-rails - ruby 2.0 rails gem 安装错误 "cannot load such file -- openssl"