【问题标题】:Writing SQL in Rails 4在 Rails 4 中编写 SQL
【发布时间】:2016-10-05 16:41:24
【问题描述】:

我有一个 payment_request 模型和一个 payment_detail 模型。在 payment_request 索引中,我需要能够按存储在 payment_details 表中的名字和姓氏进行搜索。我对编写 SQL 很陌生,可以使用一些帮助。我认为下面的查询是正确的,但不知道如何在我的 Rails 控制器中编写它,以便我可以按名称搜索。

SELECT first_name, last_name
FROM payment_details
LEFT OUTER JOIN payment_requests
ON payment_requests.id = payment_details.payment_request_id;

【问题讨论】:

  • 您可以通过地址或电子邮件地址将您现有的代码发布到 saerch for payment_details 吗?

标签: sql ruby-on-rails postgresql model-view-controller


【解决方案1】:

如果您使用 ActiveRecord 模型,则可以跳过所有这些并使用 ActiveRecord Querying Interface 构建该查询。

@payment_requests = PaymentRequest.joins(:payment_detail).where(payment_detail: {first_name: params[:first_name], last_name: params[:last_name]})

如果您打算在该索引页上显示 payment_details 数据,则应考虑在该查询中包含该信息,以避免 n+1 查询。

@payment_requests = PaymentRequest.includes(:payment_detail).where(payment_detail: { first_name: params[:first_name], last_name: params[:last_name]})

注意:您必须完全匹配才能使用上述内容,因此可能不是您想要的。

我还建议您使用Ransack gem 来构建复杂的查询。它会是这样的:

PaymentRequest.ransack(params[:q])

在你看来:

<%= f.search_field :payment_detail_first_name_or_payment_detail_last_name_cont %>

这将允许您只使用一个字段来查询两列。

【讨论】:

  • 这似乎是一个愚蠢的问题,但我会将查询放在 payment_request 还是 payment_details 控制器中?我在考虑 payment_request 控制器。
  • 我会把它保存在 payment_request 中,就像你做的那样。
  • 它对我不起作用。给我一个错误。 Matrix::PaymentRequests#index 中的 ActiveRecord::ConfigurationError 在 PaymentRequest 上找不到名为“payment_detail”的关联;也许你拼错了?
  • 我假设您在 payment_request 和 payment_detail 之间有 belongs_tohas_one 关系。
  • 然后那里发生了一些事情。也许您以不同的方式命名了该关联。错误清楚地表明Rails 在PaymentRequest 上找不到关联payment_detail。例如,您可以启动控制台并检查是否可以通过 payment_request 获取 payment_detail 数据。 PaymentRequest.first.payment_detail.
【解决方案2】:

您可以执行以下操作:

term_to_find = params[:search]
columns_to_search = %w( payment_details.first_name payment_details.last_name )
sql_conditions = []
columns_to_search.map |column_name|
  sql_conditions.push("#{column_name} ILIKE :term_to_find")
end
PaymentRequest.includes(:payment_details)
              .where(sql_conditions.join(' OR '), term_to_find: "%#{term_to_find}%")

这将找到包含您搜索的字符串的结果。示例:您在搜索中输入“bob”,它可以找到“bobby”甚至“Mr. Bob”(ILIKE 使搜索不区分大小写)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多