【问题标题】:Join and select multiple column加入并选择多个列
【发布时间】:2012-01-15 21:34:20
【问题描述】:

我正在尝试在进行连接后选择多个列。如果不在查询中的引号之间写 SQL,我找不到使用 ActiveRecord 的方法(我想避免的事情)

探索 Arel,我发现我可以使用“项目”选择多个列,但我不太确定是否应该直接使用 Arel,或者是否有办法通过 AR 实现相同的目的。

这是 Arel 中的代码:

l = Location.arel_table
r = Region.arel_table

postcode_name_with_region_code = l.where(l[:id].eq(location_id)).join(r).on(l[:region_id].eq(r[:id])).project(l[:postcode_name], r[:code])

运行此查询后,我想返回以下内容: (伪代码)

"#{:postcode_name}, #{:code}"
  1. 有没有办法使用 AR 实现相同的查询?
  2. 如果我坚持使用 Arel,如何从上述查询返回的 SelectManager 类中获取值。

提前致谢,

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3.1 arel


    【解决方案1】:

    使用 AR,无需编写任何 SQL 并假设您的模型和关联是:

    models/region.rb

    class Region < ActiveRecord::Base
      has_many :locations
    end
    

    模型/位置.rb

    class Location < ActiveRecord::Base
      belongs_to :region
    end
    

    你当然可以:

    postcode_name_with_region_code = Location.where(:id=>location_id).includes(:region).collect{|l| "#{l.postcode_name}, #{l.region.code}"}
    

    这将执行查询,然后使用 Ruby 格式化您的结果(请注意,它会返回一个数组,因为我假设可能返回多个记录)。如果只想要数组中的一项,可以使用array.first方法来引用它。

    您也可以急切地加载关联并从结果中构建您的字符串:

     my_loc = Location.find(location_id, :include=>:region)
    
     postcode_name_with_region_code = "#{my_loc.postcode_name}, #{my_loc.region.code}"
    

    【讨论】:

    • 感谢迈克的回答。这带来了另一个问题,就性能而言,与包含相比,执行连接不是更有效吗?此查询可能不会对性能造成重大影响,但我看到它在使用包含时两次查询数据库。
    • 在这种情况下,连接不会真正给您带来任何好处。如果您想尝试,请将 .includes(...) 替换为 .joins("JOIN locations.region_id ON region.id")。第二个查询是 collect 语句查询区域代码的结果。如果您也想尝试一下,我添加了一个利用关联的 AR 预加载的解决方案。
    • 谢谢,我会试一试的。在玩了一些 AR 之后,这是我开始使用的查询:Location.joins(:region).where(:id =&gt;location_id).select('locations.postcode_name, regions.code').map{|l| "#{l.postcode_name}, #{l.code}"}
    【解决方案2】:
    predicate = Location.where(:id=>location_id).includes(:region)
    predicate.ast.cores.first.projections.clear
    predicate.project(Location.arel_table[:postcode_name], Region.arel_table[:code])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多