【问题标题】:Is there a way to concatenate two fields, using Activerecord? WITHOUT using Virtual Attributes有没有办法使用 Activerecord 连接两个字段?不使用虚拟属性
【发布时间】:2015-05-14 21:54:20
【问题描述】:

我想将两个字段连接在一起,最好在两者之间留一个空格。我知道这可以在模型级别完成,但我无法预测我将混合在一起的字段和表,因此我无法为此创建虚拟属性。

以下是我正在尝试做的一个过于简单的示例。

表格:

# Product (id: integer, name: string, variety: string)
# Location (id: integer, city: string)

这将为我提供位置关系以及产品种类:

p=Product.joins(:location).group(:location_id, :variety).pluck(:city, :variety)

现在我需要将地点名称和品种名称连接在一起;那将是来自 Location 的 city 和来自 Product 的 variety

这只是一个示例,但我会使用更多我无法预测的组合。我宁愿避免为此创建虚拟属性,因为为每个可能的组合添加一个属性会非常复杂,并且使用受影响的模型创建自己的函数对于这么简单的事情来说有点太多了。

【问题讨论】:

  • 您能告诉我们更多关于您的用例的信息吗?抛开实现不谈,你会如何使用它?
  • 结果值将以表格的形式发送到一种“报告”页面,此处的值将位于其中一个单元格中。我知道在模型级别安排会更好,但由于表格的复杂性,我不是特别喜欢做这项任务。

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

我知道这是一个老问题,但它出现在 Google 搜索中,我找到了更好的答案。

@philip-hallstrom 的答案会起作用,但它会在内存中执行连接。在数据库级别执行连接会更有效,如下所示:

Product
  .joins(:location)
  .group(:location_id, :variety)
  .pluck("CONCAT_WS(' ', locations.city, products.variety)")

【讨论】:

    【解决方案2】:

    在 Rails 6.0 之后,接受的答案不再有效,您将获得 ActiveRecord::UnknownAttributeReference 异常。详情请见this PR

    现在,如果您想将更多信息传递给pluck,则需要使用Arel.sql() 方法。

    因此,扩展@dkniffin 的答案,您现在需要使用:

    Product
      .joins(:location)
      .group(:location_id, :variety)
      .pluck(Arel.sql("CONCAT_WS(' ', locations.city, products.variety)"))
    

    【讨论】:

      【解决方案3】:

      为什么你不能简单地在采摘后加入结果?像这样:

      p = Product.joins(:location).group(:location_id, :variety).
          pluck(:city, :variety).map{|e| e.join(' ')}
      

      【讨论】:

      • 因为使用 Ruby 执行该任务的效率非常低,而不是直接使用 DBMS。
      猜你喜欢
      • 2019-07-05
      • 2015-04-25
      • 1970-01-01
      • 2011-04-15
      • 2010-12-31
      • 1970-01-01
      • 2011-10-04
      • 2019-09-09
      相关资源
      最近更新 更多