Skip to content

Commit

Permalink
Merge pull request #12884 from opf/bug/48592-work-package-moved-out-o…
Browse files Browse the repository at this point in the history
…f-project-not-returned

Baseline: join with project at the time of the journal
  • Loading branch information
ulferts authored Jun 16, 2023
2 parents 8fe8ec8 + 0de4144 commit e4142af
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
13 changes: 8 additions & 5 deletions app/models/journable/historic_active_record_relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def build_arel(aliases = nil)
relation = substitute_database_table_in_where_clause(relation)
relation = add_timestamp_condition(relation)
relation = add_join_on_journables_table_with_created_at_column(relation)
relation = add_join_projects_on_journables(relation)
relation = add_join_projects_on_work_package_journals(relation)
relation = select_columns_from_the_appropriate_tables(relation)

# Based on the previous modifications, build the algebra object.
Expand Down Expand Up @@ -253,22 +253,25 @@ def journals_join_statement
#
def add_join_on_journables_table_with_created_at_column(relation)
relation \
.joins("INNER JOIN (SELECT id, created_at#{', project_id' if include_projects?(relation)} " \
.joins("INNER JOIN (SELECT id, created_at " \
"FROM \"#{model.table_name}\") AS journables " \
"ON \"journables\".\"id\" = \"journals\".\"journable_id\"")
end

# Join the projects table on journables if :project is in the includes.
# Join the projects table on work_package_journals if :project is in the includes.
# It is needed when projects are filtered by id, and has to be done manually
# as eager_loading is disabled.
# It needs to be `work_package_journals` and not `journables` (the subselect of the work_packages table)
# because the journables table will contain the current project and not the project the work package was
# in at the time of the journal.
# Does not work yet for other includes.
#
def add_join_projects_on_journables(relation)
def add_join_projects_on_work_package_journals(relation)
if include_projects?(relation)
relation
.except(:includes, :eager_load, :preload)
.joins('LEFT OUTER JOIN "projects" ' \
'ON "projects"."id" = "journables"."project_id"')
'ON "projects"."id" = "work_package_journals"."project_id"')
else
relation
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ def create_journal(journable:, timestamp:, attributes: {})
it "joins the projects table" do
sql = subject.to_sql.tr('"', '')
expect(sql).to include \
"LEFT OUTER JOIN projects ON projects.id = journables.project_id"
"LEFT OUTER JOIN projects ON projects.id = work_package_journals.project_id"
expect(sql).to include \
"WHERE projects.id = #{project.id}"
end
Expand Down
25 changes: 25 additions & 0 deletions spec/models/journable/timestamps_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,31 @@ def create_journal(journable:, timestamp:, attributes: {})
end
end
end

context "when including projects and filtering on it (e.g. done by the work package query)" do
before do
# Pretend the work package had been moved to a different project on wednesday
wednesday_journal.data.update_column(:project_id, work_package.project_id + 1)
end

subject { WorkPackage.at_timestamp(timestamp).includes(:project).where(projects: { id: [work_package.project.id] }) }

context "when the work package was in the filtered for project at that time" do
let(:timestamp) { monday }

it "returns the work package" do
expect(subject).to eq [work_package]
end
end

context "when the work package wasn't in the filtered for project at that time" do
let(:timestamp) { wednesday }

it "does not return the work package" do
expect(subject).to be_empty
end
end
end
end

describe "#at_timestamp" do
Expand Down

0 comments on commit e4142af

Please sign in to comment.