Arel: Left outer join using characters

I have this use case where I get symbolized deep associations from a specific model, and I have to fulfill certain requests that are related to using external connections. How to do this without resorting to writing full SQL manually?

Answers that I don't want: - use includes (doesn't allow deep associations very well (.includes (: cars => [: windows ,: engine => [: ignition] ..... works unexpectedly), and I don't want its side effects) - write SQL itself (sorry, this is 2013, support for cross-db, etc. etc.), and the objects that I get are read_only, more side effects)

I would like to have an Arel solution. I know that using isl_table from models I can build SQL expressions, there is also DSL for connections, but for some reason I can not use it in the joins method from the model:

car = Car.arel_table
engine = Engine.arel_table

eng_exp = car.join(engine).on(car[:engine_id].eq(engine[:id]))
eng_exp.to_sql #=> GOOD! very nice!
Car.joins(eng_exp) #=> Breaks!!

Why this does not work, marries me. I don’t know exactly what is missing. But this is the closest to the solution that I have now. If someone can help me fill out my example or give me a nice workaround or tell me when Rails will enable such an explicitly needed feature, I will have my eternal thanks.

+5
source share
3 answers

I found a blog post that addresses this issue: http://blog.donwilson.net/2011/11/constructing-a-less-than-simple-query-with-rails-and-arel/

( ), :

car = Car.arel_table
engine = Engine.arel_table   

sql = car.project(car[Arel.star])
        .join(engine, Arel::Nodes::OuterJoin).on(car[:engine_id].eq(engine[:id]))

Car.find_by_sql(sql)
+6

, , :

- .joins, .create_join .create_on:

join_on = car.create_on(car[:engine_id].eq(engine[:id]))
eng_join = car.create_join(engine, join_on, Arel::Nodes::OuterJoin)

Car.joins(eng_join)

.join_sources :

eng_exp = car.join(engine, Arel::Nodes::OuterJoin).on(car[:engine_id].eq(engine[:id]))
Car.joins(eng_exp.join_sources)
+6

AREL, Squeel. -

Car.joins{engine.outer}.where(...)

, :

belongs_to :engine
0

All Articles