diff --git a/.ai/wheels/snippets/model-snippets.md b/.ai/wheels/snippets/model-snippets.md index db919550ba..23a8663941 100755 --- a/.ai/wheels/snippets/model-snippets.md +++ b/.ai/wheels/snippets/model-snippets.md @@ -8,7 +8,7 @@ Common model patterns and code snippets for Wheels applications. component extends="Model" { function config() { // Table mapping (if different from convention) - table("custom_table_name"); + tableName("custom_table_name"); // Associations hasMany("comments"); diff --git a/changelog.d/3079-tablename-setter.fixed.md b/changelog.d/3079-tablename-setter.fixed.md new file mode 100644 index 0000000000..bd74d02d27 --- /dev/null +++ b/changelog.d/3079-tablename-setter.fixed.md @@ -0,0 +1 @@ +- `tableName("my_table")` now works as a model table setter: when called with a name it delegates to `table()` and returns the resolved name, instead of silently no-opping and leaving the model on its convention table. The zero-argument getter form is unchanged (#3079) diff --git a/vendor/wheels/model/miscellaneous.cfc b/vendor/wheels/model/miscellaneous.cfc index fd763bdec9..fd3b3fac06 100644 --- a/vendor/wheels/model/miscellaneous.cfc +++ b/vendor/wheels/model/miscellaneous.cfc @@ -170,11 +170,19 @@ component { /** * Returns the name of the database table that this model is mapped to. + * When called with a `name` argument it acts as a setter, delegating to `table()`, + * and returns the resolved name. This makes the commonly-reached-for + * `tableName("my_table")` form in `config()` work instead of silently no-opping. * * [section: Model Class] * [category: Miscellaneous Functions] + * + * @name When provided, sets the table this model maps to (alias for `table()`). */ - public string function tableName() { + public string function tableName(any name) { + if (StructKeyExists(arguments, "name")) { + table(arguments.name); + } if ($get("lowerCaseTableNames")) { return LCase(variables.wheels.class.tableName); } else { diff --git a/vendor/wheels/tests/specs/model/miscellaneousSpec.cfc b/vendor/wheels/tests/specs/model/miscellaneousSpec.cfc index a7d7dc84ce..c45c6c5ccb 100644 --- a/vendor/wheels/tests/specs/model/miscellaneousSpec.cfc +++ b/vendor/wheels/tests/specs/model/miscellaneousSpec.cfc @@ -159,6 +159,33 @@ component extends="wheels.WheelsTest" { expect(users.recordcount).toBe(3) }) }) + + describe("Tests that tableName acts as a setter when given a name - issue 3079", () => { + + afterEach(() => { + // Restore the mapped table so the override never leaks into other specs + g.model("author").table("c_o_r_e_authors") + }) + + it("delegates to table() when a name argument is passed", () => { + author = g.model("author") + author.tableName("tbl_authors_override") + + expect(author.tableName()).toBe("tbl_authors_override") + }) + + it("returns the newly set name from the setter call", () => { + author = g.model("author") + + expect(author.tableName("tbl_authors_override")).toBe("tbl_authors_override") + }) + + it("still returns the current name when called with no argument", () => { + author = g.model("author") + + expect(author.tableName()).toBe("c_o_r_e_authors") + }) + }) } function assert_pagination(required string handle) {