.merge()在此查询中正在做什么?

时间:2018-10-19 14:15:06

标签: sql ruby-on-rails activerecord rails-activerecord

由于merge的情况,即使在阅读了文档之后,我还是对如何解释该查询感到困惑。

我想知道下面对应的SQL查询是什么

Analise.joins(dape: [empresa: :area_atuacao])
       .merge(@dapes)
       .where(analises: { atual: true })
       .pluck('analises.img')

对此查询调用to_sql的输出:

=> "SELECT \"analises\".* 
    FROM \"analises\" 
    INNER JOIN \"dapes\" ON \"dapes\".\"id\" = \"analises\".\"dape_id\" 
    INNER JOIN \"empresas\" ON \"empresas\".\"id\" = \"dapes\".\"empresa_id\" 
    INNER JOIN \"areas_atuacao\" ON \"areas_atuacao\".\"id\" = \"empresas\".\"area_atuacao_id\" 
    WHERE \"analises\".\"atual\" = 't'"

2 个答案:

答案 0 :(得分:3)

  

合并(其他)
  合并其他条件,如果其他条件是ActiveRecord :: Relation。
  -Rails API Docs

一个常见的示例是使用它来将搜索条件合并在一起:

@cities = City.all
@cities = @cities.merge(City.where(country: params[:country])) if params[:country]
@cities = @cities.merge(City.where(name: params[:name])) if params[:name]

您也可以使用它在连接的表上创建条件,如本示例中的docs所示:

Post.where(published: true)
    .joins(:comments)
    .merge( Comment.where(spam: false) )

这将创建与以下查询相同的查询:

Post.where(published: true)
    .joins(:comments)
    .where(comments: { spam: false })

示例中的确切查询取决于实例变量@dapes中定义的范围。但是从SQL生成的.merge(@dapes)来看似乎没有任何作用。例如,@dapes = Dape.all就是这种情况。

合并没有where子句的条件不会执行任何操作:

irb(main):003:0> User.merge(User.all)
  User Load (0.6ms)  SELECT  "users".* FROM "users" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
irb(main):004:0> 

答案 1 :(得分:1)

在这里,您的格式更好,可读性更好。合并用于转移您的条件,因此不会覆盖任何内容。

SELECT analises.* 
FROM analises
    INNER JOIN dapes ON dapes.id = analises.dape_id
    INNER JOIN empresas ON empresas.id = dapes.empresa_id
    INNER JOIN areas_atuacao ON areas_atuacao.id = empresas.area_atuacao_id
WHERE analises.atual = 't'

似乎在连接表时使用.merge()来更具体地说明您要联接的对象。

在这种情况下,您.merge(@dapes)似乎正在将表合并到@dapes的所有值上。

一种更好地了解.merge(@dapes)对查询有什么影响的方法是再次运行to_sql命令,以更改sql的方式。

脚注

我采用了从您运行的第一个to_sql中生成的sql,并将其输入到Scuttle Editor中,并获得了以下rails命令。我不知道这是否有帮助,但我只是认为这是值得深思的!

Analise.select(Analise.arel_table[Arel.star]).where(Analise.arel_table[:atual].eq('t')).joins(
  Analise.arel_table.join(Dape.arel_table).on(
    Dape.arel_table[:id].eq(Analise.arel_table[:dape_id])
  ).join_sources
).joins(
  Analise.arel_table.join(Empresa.arel_table).on(
    Empresa.arel_table[:id].eq(Dape.arel_table[:empresa_id])
  ).join_sources
).joins(
  Analise.arel_table.join(AreasAtuacao.arel_table).on(
    AreasAtuacao.arel_table[:id].eq(Empresa.arel_table[:area_atuacao_id])
  ).join_sources
)