Skip to content

Commit

Permalink
Wrapping update queries with joins in a subquery. Fixes #827 (#998)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwoertink authored Feb 10, 2024
1 parent 641937e commit f1bfffc
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
9 changes: 9 additions & 0 deletions spec/avram/queryable_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,15 @@ describe Avram::Queryable do
bucket = bucket.reload
bucket.names.should eq(["Rey"])
end

it "updates with joins" do
manager1 = ManagerFactory.create(&.name("Mr. Krabs"))
manager2 = ManagerFactory.create(&.name("Mr. Robot"))
EmployeeFactory.create(&.name("Spongebob Alderson").manager_id(manager1.id))
Employee::BaseQuery.new.where_manager(Manager::BaseQuery.new.id(manager1.id)).update(manager_id: manager2.id)
manager1.employees!.first?.should be_nil
manager2.employees!.first.name.should eq("Spongebob Alderson")
end
end

describe "#delete" do
Expand Down
10 changes: 9 additions & 1 deletion src/avram/query_builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,17 @@ class Avram::QueryBuilder
clone.statement_for_update!(params, returning?)
end

# Creates the SQL for updating. If any joins are present, it
# moves the WHERE clause to a subquery allowing for joins
def statement_for_update!(params, return_columns returning? : Bool = true)
sql = ["UPDATE #{table}", set_sql_clause(params)]
sql += sql_condition_clauses
if joins_sql.presence
sql += ["WHERE EXISTS", "(", select_sql]
sql += sql_condition_clauses
sql += [")"]
else
sql += sql_condition_clauses
end
sql += ["RETURNING #{@selections}"] if returning?

join_sql sql
Expand Down

0 comments on commit f1bfffc

Please sign in to comment.