Skip to content

Instantly share code, notes, and snippets.

@sighmin
Created June 4, 2015 14:17
Show Gist options
  • Save sighmin/052975043b70bb705d96 to your computer and use it in GitHub Desktop.
Save sighmin/052975043b70bb705d96 to your computer and use it in GitHub Desktop.
Fiddling with the shockingly documented AREL library to produce a join using an aggregate SQL function (max) in the hopes I'd be able to chain it. ALAS! Only after 2 hours did I realize this ain't gonna works yo.
class Checklist < ActiveRecord::Base
scope :current, -> {
c = Arel::Table.new(:checklists, as: 'c')
r = Arel::Table.new(:checklists, as: 'r')
sql = c.project(Arel.star)
.join(r.project(r[:version_id], r[:version_no].maximum.as('vno'))
.group(r[:version_id]).as('r'))
.on(r[:version_id].eq(c[:version_id])
.and(r[:vno].eq(c[:version_no])))
find_by_sql(sql)
}
# which is equivalent to:
# find_by_sql("
# SELECT c.*
# FROM checklists c
# INNER JOIN (
# SELECT version_id, MAX(version_no) as vno
# FROM checklists
# GROUP BY version_id
# ) r
# ON r.version_id = c.version_id
# AND r.vno = c.version_no
# ")
#
# or:
# SELECT c.*
# FROM checklists c
# WHERE version_no = (
# SELECT version_no
# FROM checklists c2
# WHERE c2.version_id = c.version_id
# ORDER BY c2.version_no desc
# LIMIT 1
# )
#
# Don't ask me which is faster, I don't know.
end
# ...
create_table "checklists", force: :cascade do |t|
t.string "name", limit: 255, null: false
t.text "description", limit: 65535
t.integer "creator_id", limit: 4
t.string "type", limit: 255, default: "CustomChecklist", null: false
t.integer "version_id", limit: 4
t.integer "version_no", limit: 4, null: false
t.integer "duration", limit: 4
t.text "meta_data", limit: 65535
t.datetime "schedule_start"
t.datetime "schedule_end"
t.text "schedule", limit: 65535
t.datetime "deleted_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
# ...
@sighmin
Copy link
Author

sighmin commented Jun 4, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment