代码之家  ›  专栏  ›  技术社区  ›  Eduardo Rocha

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

  •  2
  • Eduardo Rocha  · 技术社区  · 6 年前

    我对如何解释这个查询有点困惑,这都是因为 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 回复  |  直到 6 年前
        1
  •  3
  •   max Mike Williams    6 年前

    合并(其他)
    如果对方是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]
    

    您还可以使用它在已联接的表上创建条件,如本例中的文档:

    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> 
    
        2
  •  1
  •   B. Cratty    6 年前

    这里是您的格式,为了更好的可读性。合并用于在条件上进行传输,以便不覆盖任何内容。

    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如何更改。

    脚注

    我采用了从第一个 ToSQL 您运行并将其输入到scattle编辑器中,得到了以下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
    )