QA@IT
«回答へ戻る

回答を投稿

ActiveRecord では、質問文にあるように SQL を書く以外には alias を指定する方法はなさそうです。直接 Arel を使えば可能です。

deals = Deal.arel_table
managers = User.arel_table.alias("managers")

Deal.joins(
  deals.join(managers)
    .on(
      Arel::Nodes::And.new([
        managers[:id].eq(deals[:manager_id]),
        managers[:type].eq("Manager")
      ])
    )
    .join_sources
    .first
).where("LOWER(managers.name) LIKE ?", "%foo%")
# => SELECT "deals".* FROM "deals" INNER JOIN "users" "managers" ON "managers"."id" = "deals"."manager_id" AND "managers"."type" = 'Manager' WHERE (LOWER(managers.name) LIKE '%foo%')

もっとも、質問文にあるように SQL を直接書いても、ほとんどの場合、問題も起きず、わかりやすいように思います。

私が書くなら、alias を明示して join するスコープと、それを使って絞り込みするクラスメソッドを作りますかね。

class Deal
  scope :with_managers, -> {
    joins(<<-SQL
      INNER JOIN "users" AS "managers"
        ON "managers"."id" = "deals"."manager_id" AND
           "managers"."type" = 'Manager'
    SQL
    )
  }

  def self.search_by_manager_name(q)
    with_managers.where("LOWER(managers.name) LIKE ?", "%#{q.downcase}%")
  end
end

参考:
https://github.com/rails/arel/blob/master/README.markdown
http://stackoverflow.com/questions/5072709/arel-joins-and-rails-queries

ActiveRecord では、質問文にあるように SQL を書く以外には alias を指定する方法はなさそうです。直接 Arel を使えば可能です。

```ruby
deals = Deal.arel_table
managers = User.arel_table.alias("managers")

Deal.joins(
  deals.join(managers)
    .on(
      Arel::Nodes::And.new([
        managers[:id].eq(deals[:manager_id]),
        managers[:type].eq("Manager")
      ])
    )
    .join_sources
    .first
).where("LOWER(managers.name) LIKE ?", "%foo%")
# => SELECT "deals".* FROM "deals" INNER JOIN "users" "managers" ON "managers"."id" = "deals"."manager_id" AND "managers"."type" = 'Manager' WHERE (LOWER(managers.name) LIKE '%foo%')
```

もっとも、質問文にあるように SQL を直接書いても、ほとんどの場合、問題も起きず、わかりやすいように思います。

私が書くなら、alias を明示して join するスコープと、それを使って絞り込みするクラスメソッドを作りますかね。

```ruby
class Deal
  scope :with_managers, -> {
    joins(<<-SQL
      INNER JOIN "users" AS "managers"
        ON "managers"."id" = "deals"."manager_id" AND
           "managers"."type" = 'Manager'
    SQL
    )
  }

  def self.search_by_manager_name(q)
    with_managers.where("LOWER(managers.name) LIKE ?", "%#{q.downcase}%")
  end
end
```

参考:
https://github.com/rails/arel/blob/master/README.markdown
http://stackoverflow.com/questions/5072709/arel-joins-and-rails-queries