diff --git a/e2e/test/scenarios/models/helpers/e2e-models-metadata-helpers.js b/e2e/support/helpers/e2e-models-metadata-helpers.js
similarity index 100%
rename from e2e/test/scenarios/models/helpers/e2e-models-metadata-helpers.js
rename to e2e/support/helpers/e2e-models-metadata-helpers.js
diff --git a/e2e/support/helpers/index.js b/e2e/support/helpers/index.js
index 0a96b38ee34b7e9735376ce55c652661315826b8..5967af05d1c5dca6ee2227074dcb2c9522eab92b 100644
--- a/e2e/support/helpers/index.js
+++ b/e2e/support/helpers/index.js
@@ -28,3 +28,4 @@ export * from "./e2e-permissions-helpers";
 export * from "./e2e-visual-tests-helpers";
 export * from "./e2e-users-helpers";
 export * from "./e2e-viz-settings-helpers";
+export * from "./e2e-models-metadata-helpers";
diff --git a/e2e/test/scenarios/joins/reproductions/27380-dashboard-drops-joined-fields-on-zoom-in.cy.spec.js b/e2e/test/scenarios/joins/reproductions/27380-dashboard-drops-joined-fields-on-zoom-in.cy.spec.js
index 742b31b6ec768d2fa06e6c04208a9b0c938313d7..9d7b4bd28e3dfb403ae14be8b39d814360f57d51 100644
--- a/e2e/test/scenarios/joins/reproductions/27380-dashboard-drops-joined-fields-on-zoom-in.cy.spec.js
+++ b/e2e/test/scenarios/joins/reproductions/27380-dashboard-drops-joined-fields-on-zoom-in.cy.spec.js
@@ -3,50 +3,49 @@ import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
 
 const { ORDERS, ORDERS_ID, PRODUCTS } = SAMPLE_DATABASE;
 
-const questionDetails = {
-  query: {
-    "source-table": ORDERS_ID,
-    aggregation: [["count"]],
-    breakout: [
-      [
-        "field",
-        PRODUCTS.CREATED_AT,
-        { "source-field": ORDERS.PRODUCT_ID, "temporal-unit": "month" },
-      ],
-    ],
-  },
-  display: "line",
-};
-
-describe.skip("issue 27380", () => {
+describe("issue 27380", () => {
   beforeEach(() => {
     cy.intercept("POST", "/api/dataset").as("dataset");
 
     restore();
     cy.signInAsAdmin();
+  });
 
+  it("should not drop fields from joined table on dashboard 'zoom-in' (metabase#27380)", () => {
+    const questionDetails = {
+      query: {
+        "source-table": ORDERS_ID,
+        aggregation: [["count"]],
+        breakout: [
+          [
+            "field",
+            PRODUCTS.CREATED_AT,
+            { "source-field": ORDERS.PRODUCT_ID, "temporal-unit": "month" },
+          ],
+        ],
+      },
+      display: "line",
+    };
     cy.createQuestionAndDashboard({ questionDetails }).then(
       ({ body: { dashboard_id } }) => {
         visitDashboard(dashboard_id);
       },
     );
-  });
 
-  it("should not drop fields from joined table on dashboard 'zoom-in' (metabase#27380)", () => {
     // Doesn't really matter which 'circle" we click on the graph
     cy.get("circle").last().realClick();
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Zoom in").click();
+    cy.findByText("See this month by week").click();
     cy.wait("@dataset");
 
     // Graph should still exist
     // Let's check only the y-axis label
-    cy.get("y-axis-label").invoke("text").should("eq", "Count");
+    cy.get(".y-axis-label").invoke("text").should("eq", "Count");
 
     cy.icon("notebook").click();
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
     cy.findByText("Pick a column to group by").should("not.exist");
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(/Products? → Created At: Month/);
+    cy.findByText("Product → Created At: Week");
   });
 });
diff --git a/e2e/test/scenarios/models/model-indexes.cy.spec.js b/e2e/test/scenarios/models/model-indexes.cy.spec.js
index e7f87f843ee09b1c5d8edf4d5e513c5737fbc0a1..a0857c9e1ee2f805ca6f71fcb3373d036d3e0ce3 100644
--- a/e2e/test/scenarios/models/model-indexes.cy.spec.js
+++ b/e2e/test/scenarios/models/model-indexes.cy.spec.js
@@ -3,10 +3,10 @@ import {
   openQuestionActions,
   popover,
   sidebar,
+  openColumnOptions,
 } from "e2e/support/helpers";
 
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import { openColumnOptions } from "./helpers/e2e-models-metadata-helpers";
 
 const { PRODUCTS_ID, PEOPLE_ID } = SAMPLE_DATABASE;
 
diff --git a/e2e/test/scenarios/models/models-metadata.cy.spec.js b/e2e/test/scenarios/models/models-metadata.cy.spec.js
index 5753a534cd815978020992f71b44b409a4200835..23d63442c143df3598b6da4ae8698d2c4efb94d6 100644
--- a/e2e/test/scenarios/models/models-metadata.cy.spec.js
+++ b/e2e/test/scenarios/models/models-metadata.cy.spec.js
@@ -7,16 +7,14 @@ import {
   openQuestionActions,
   questionInfoButton,
   addOrUpdateDashboardCard,
-} from "e2e/support/helpers";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import { startQuestionFromModel } from "./helpers/e2e-models-helpers";
-import {
   openColumnOptions,
   renameColumn,
   setColumnType,
   mapColumnTo,
   setModelMetadata,
-} from "./helpers/e2e-models-metadata-helpers";
+} from "e2e/support/helpers";
+import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
+import { startQuestionFromModel } from "./helpers/e2e-models-helpers";
 
 const { PEOPLE, PRODUCTS, PRODUCTS_ID, REVIEWS } = SAMPLE_DATABASE;
 
diff --git a/e2e/test/scenarios/models/reproductions/23024-cannot-apply-dash-filter-native-model.cy.spec.js b/e2e/test/scenarios/models/reproductions/23024-cannot-apply-dash-filter-native-model.cy.spec.js
index dc1ad8974e4b2e40da85c3ce186a7fee7a52a960..bef30bfcac8be6a0f72855a13ba81744c78c52e9 100644
--- a/e2e/test/scenarios/models/reproductions/23024-cannot-apply-dash-filter-native-model.cy.spec.js
+++ b/e2e/test/scenarios/models/reproductions/23024-cannot-apply-dash-filter-native-model.cy.spec.js
@@ -4,9 +4,9 @@ import {
   popover,
   restore,
   visitDashboard,
+  setModelMetadata,
 } from "e2e/support/helpers";
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import { setModelMetadata } from "../helpers/e2e-models-metadata-helpers";
 
 const { PRODUCTS } = SAMPLE_DATABASE;
 
diff --git a/frontend/src/metabase-lib/queries/utils/drilldown.js b/frontend/src/metabase-lib/queries/utils/drilldown.js
index f538685fd798702a914cf6059213403eeea44d2d..845a1cc9b858a727f16224508a09961567d7023b 100644
--- a/frontend/src/metabase-lib/queries/utils/drilldown.js
+++ b/frontend/src/metabase-lib/queries/utils/drilldown.js
@@ -8,7 +8,10 @@ import {
 } from "metabase-lib/types/utils/isa";
 import { TYPE } from "metabase-lib/types/constants";
 
-import { isExpressionField } from "metabase-lib/queries/utils/field-ref";
+import {
+  isExpressionField,
+  isSameField,
+} from "metabase-lib/queries/utils/field-ref";
 import { FieldDimension } from "metabase-lib/Dimension";
 // Drill-down progressions are defined as a series of steps, where each step has one or more dimension <-> breakout
 // transforms.
@@ -451,7 +454,13 @@ function columnToFieldDimension(column, metadata) {
     return;
   }
 
-  const dimension = new FieldDimension(column.id, null, metadata);
+  let dimension = new FieldDimension(column.id, null, metadata);
+  // When aggregating fields from foreign keys, `dimension`'s options could be
+  // missing `source-field`, so if `dimension` still is the same field as `column.field_ref`,
+  // try parsing the `ref_field` directly as it might contain missing options.
+  if (isSameField(column.field_ref, dimension.mbql())) {
+    dimension = FieldDimension.parseMBQL(column.field_ref, metadata);
+  }
 
   if (column.unit) {
     return dimension.withTemporalUnit(column.unit);