with_model 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 809e5984c60e2fa27b71d3d3ce7664feae0a3b2c7a59f345e2a94a819affb623
4
- data.tar.gz: 5e8b519ef7d338aa754755efd065af68b718e6dc1f96fe27632266752e7b4990
3
+ metadata.gz: 0bac7bd2d2e529887f1e9bd82117cc809f23b336a8acaa2b90e4fb9305c96fe2
4
+ data.tar.gz: 1867b36f42957d744858fcefe70f53c58b0c5f39b951a4749a969c39c46b42f0
5
5
  SHA512:
6
- metadata.gz: cf09e4aabe724638f054a54199d62a61ae9efd0cca28485412f85fd082a99f104d4f538bd7041f1777c9380398e7d1497d5f01dcc07cb5fdacc116ad3e7dd69f
7
- data.tar.gz: 6f795b756e9b33abd148d51010a0afb80e01660af35c76d1a98a634c6b2d31c38a616e94aeff99c6d8b19b019c69b994c9b5dc21e69439fbbcb004528dc3606b
6
+ metadata.gz: eec34fe045c932273600775ccf7b2719dad1d10d6631baf43b9b7d54eec50bc4592d24cc1da1e9af7a844e7fbc73f707a0027d9f58c891afd18fb934e1f796d9
7
+ data.tar.gz: 5720ad24f60c91dee5b1eac354a0ca3d3f00d6c65e5d2f45fc76a310d6330564f43ec14924f168edc064121e9cc70b4ca7483c08a33587ea90f20031fff3fba2
@@ -1,8 +1,24 @@
1
1
  version: 2
2
2
  updates:
3
- - package-ecosystem: bundler
4
- directory: "/"
5
- schedule:
6
- interval: daily
7
- time: "10:00"
8
- open-pull-requests-limit: 10
3
+ # Gemfile.lock is not checked in and the Gemfile deliberately leaves versions
4
+ # to Bundler, so there is nothing here for Dependabot to bump routinely. It is
5
+ # listed to receive security advisories for the constraints that do exist.
6
+ - package-ecosystem: bundler
7
+ directory: "/"
8
+ schedule:
9
+ interval: weekly
10
+ day: saturday
11
+ open-pull-requests-limit: 10
12
+
13
+ # The workflow pins actions by major version, which does not float across
14
+ # majors: actions/checkout sat four majors behind until someone noticed by
15
+ # hand. One grouped pull request keeps them current without a PR per action.
16
+ - package-ecosystem: github-actions
17
+ directory: "/"
18
+ schedule:
19
+ interval: weekly
20
+ day: saturday
21
+ groups:
22
+ actions:
23
+ patterns:
24
+ - "*"
@@ -6,50 +6,85 @@ on:
6
6
  - master
7
7
  - github-actions
8
8
  pull_request:
9
+ schedule:
10
+ - cron: "0 18 * * 6" # Saturdays at 12pm CST
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ concurrency:
17
+ group: ${{ github.workflow }}-${{ github.ref }}
18
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
9
19
 
10
20
  jobs:
11
21
  test:
22
+ name: Ruby ${{ matrix.ruby-version }} / ${{ matrix.active-record.label }}
12
23
  runs-on: ubuntu-latest
24
+ timeout-minutes: 20
13
25
  env:
14
26
  CI: true
15
27
  strategy:
16
28
  fail-fast: false
17
29
  matrix:
18
- ruby-version: ['3.1', '3.2', '3.3', '3.4']
19
- active-record-version-env:
20
- - ACTIVE_RECORD_VERSION="~> 7.0.0"
21
- - ACTIVE_RECORD_VERSION="~> 7.1.0"
22
- - ACTIVE_RECORD_VERSION="~> 7.2.0"
23
- - ACTIVE_RECORD_VERSION="~> 8.0.0"
30
+ ruby-version: ["3.3", "3.4", "4.0"]
31
+ active-record:
32
+ - label: AR 7.2
33
+ env: ACTIVE_RECORD_VERSION=~> 7.2.0
34
+ - label: AR 8.0
35
+ env: ACTIVE_RECORD_VERSION=~> 8.0.0
36
+ - label: AR 8.1
37
+ env: ACTIVE_RECORD_VERSION=~> 8.1.0
24
38
  allow-failure: [false]
25
- exclude:
26
- - ruby-version: '3.1'
27
- active-record-version-env: ACTIVE_RECORD_VERSION="~> 8.0.0"
28
39
  include:
29
- - ruby-version: '3.4'
30
- active-record-version-env: ACTIVE_RECORD_BRANCH="main"
40
+ - ruby-version: "4.0"
41
+ active-record:
42
+ label: AR main
43
+ env: ACTIVE_RECORD_BRANCH=main
31
44
  allow-failure: true
32
- - ruby-version: '3.4'
33
- active-record-version-env: ACTIVE_RECORD_BRANCH="8-0-stable"
45
+ - ruby-version: "4.0"
46
+ active-record:
47
+ label: AR 8-1-stable
48
+ env: ACTIVE_RECORD_BRANCH=8-1-stable
34
49
  allow-failure: true
35
- - ruby-version: '3.4'
36
- active-record-version-env: ACTIVE_RECORD_BRANCH="7-2-stable"
50
+ - ruby-version: "4.0"
51
+ active-record:
52
+ label: AR 8-0-stable
53
+ env: ACTIVE_RECORD_BRANCH=8-0-stable
37
54
  allow-failure: true
38
- - ruby-version: '3.4'
39
- active-record-version-env: ACTIVE_RECORD_BRANCH="7-1-stable"
55
+ - ruby-version: "4.0"
56
+ active-record:
57
+ label: AR 7-2-stable
58
+ env: ACTIVE_RECORD_BRANCH=7-2-stable
40
59
  allow-failure: true
41
- - ruby-version: '3.4'
42
- active-record-version-env: ACTIVE_RECORD_BRANCH="7-0-stable"
60
+ # A canary for the next Ruby, which cannot fail the build.
61
+ - ruby-version: ruby-head
62
+ active-record:
63
+ label: AR 8.1
64
+ env: ACTIVE_RECORD_VERSION=~> 8.1.0
43
65
  allow-failure: true
44
66
  continue-on-error: ${{ matrix.allow-failure }}
45
67
  steps:
46
- - uses: actions/checkout@v3
47
- - name: Set up Ruby
48
- uses: ruby/setup-ruby@v1
49
- with:
50
- ruby-version: ${{ matrix.ruby-version }}
51
- bundler-cache: true
52
- - name: Update bundle
53
- run: ${{ matrix.active-record-version-env }} bundle update
54
- - name: Run tests
55
- run: ${{ matrix.active-record-version-env }} bin/rake
68
+ - uses: actions/checkout@v7
69
+ # Set the version here rather than prefixing each command, so the matrix
70
+ # value reaches the environment without being interpolated into a script.
71
+ - name: Select Active Record version
72
+ env:
73
+ ACTIVE_RECORD_ENV: ${{ matrix.active-record.env }}
74
+ run: echo "$ACTIVE_RECORD_ENV" >> "$GITHUB_ENV"
75
+ - name: Set up Ruby
76
+ uses: ruby/setup-ruby@v1
77
+ with:
78
+ ruby-version: ${{ matrix.ruby-version }}
79
+ bundler-cache: true
80
+ cache-version: ${{ matrix.active-record.env }}
81
+ # Gemfile.lock is not checked in, so this resolves the newest gems that
82
+ # satisfy the Gemfile on each run rather than a recorded set. `--all` is
83
+ # what Bundler 4, shipped with Ruby 4.0, wants for that.
84
+ - name: Update bundle
85
+ run: bundle update --all
86
+ # Not bin/rake: bin/ holds generated binstubs and is not checked in, and
87
+ # whether bundling writes them there varies by Bundler version - Bundler 4
88
+ # does not, which left Ruby 4.0 with no binstub to run.
89
+ - name: Run tests
90
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ### 2.3.0
2
+
3
+ - Add `table(false)` to create no table, so that a model whose superclass is a
4
+ concrete Active Record class uses single table inheritance.
5
+ - Accept a String, a Symbol, or a callable for `superclass:`, resolved for each
6
+ example, so that another `with_model` model can be the superclass.
7
+ - Raise `WithModel::InvalidSuperclass` for a `superclass:` that cannot be used,
8
+ and `WithModel::MissingSuperclass` for a name that resolves to nothing. Both
9
+ are `ArgumentError`s, and the latter is an `InvalidSuperclass`, so either can
10
+ be rescued as narrowly as needed.
11
+ - Deprecate omitting `table`, which currently creates a table with only an id
12
+ column. In 3.0 it will create no table.
13
+ - Create minitest models in the order they are declared, so that a model can
14
+ refer to another model declared above it.
15
+ - Add support for Active Record 8.1.
16
+ - Require Active Record 7.2 or later.
17
+ - Add support for Ruby 4.0.
18
+ - Require Ruby 3.3 or later.
19
+
1
20
  ### 2.2.0
2
21
 
3
22
  - Fix dependency tracking issue when `cache_classes: true` is set in Rails 7+.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,83 @@
1
+ # Contributing to with_model
2
+
3
+ If you experience a bug, we welcome you to report it. Please include a minimal
4
+ example showing the code you ran, what happened, and what you expected to happen
5
+ instead — a failing `with_model` block is ideal, since it can be dropped straight
6
+ into the suite. If you can fix the bug and open a pull request, it will get
7
+ resolved sooner, but don't hesitate to report an issue you don't know how to fix.
8
+
9
+ If you have a substantial feature in mind, consider opening an issue to discuss
10
+ it first. We may have thought about it already, and can sometimes save you a
11
+ detour.
12
+
13
+ When in doubt, go ahead and open a pull request. If something needs rethinking,
14
+ we will do our best to say so clearly. Don't be discouraged if we ask you to
15
+ change your code — we appreciate the work, and we also have opinions about style
16
+ and object design.
17
+
18
+ ## Supported versions
19
+
20
+ The [gemspec](./with_model.gemspec) declares the minimum supported Ruby and
21
+ Active Record, and the [CI workflow](./.github/workflows/ci.yml) lists every
22
+ combination actually tested. It can be hard to try them all locally, so please
23
+ avoid anything that only works on the newest of either.
24
+
25
+ ## Running the tests
26
+
27
+ The suite runs against both supported test harnesses, so `with_model` has to work
28
+ under each:
29
+
30
+ - `spec/` covers behavior under RSpec.
31
+ - `test/` covers the minitest life cycle — the setup and teardown hooks, and
32
+ their ordering — rather than repeating the specs.
33
+
34
+ Run everything, including the linter, with:
35
+
36
+ ```sh
37
+ bundle exec rake
38
+ ```
39
+
40
+ `bin/` holds generated binstubs and is not checked in. Whether bundling writes
41
+ them for you depends on your Bundler version, so create them once if you would
42
+ rather type `bin/rake`:
43
+
44
+ ```sh
45
+ bundle binstubs --all
46
+ ```
47
+
48
+ Our automated tests begin by updating every gem to its newest version. That is
49
+ deliberate: we would rather find out about an incompatibility from our own build
50
+ than from a bug report. `Gemfile.lock` is not checked in, so you can do the same
51
+ at any time with `bundle update --all`.
52
+
53
+ To try a particular Active Record, set `ACTIVE_RECORD_VERSION` to a version
54
+ requirement and update the bundle:
55
+
56
+ ```sh
57
+ ACTIVE_RECORD_VERSION="~> 8.1.0" bundle update --all
58
+ ACTIVE_RECORD_VERSION="~> 8.1.0" bundle exec rake
59
+ ```
60
+
61
+ To test against Active Record from git instead — an unreleased branch, or `main`
62
+ — set `ACTIVE_RECORD_BRANCH`:
63
+
64
+ ```sh
65
+ ACTIVE_RECORD_BRANCH=main bundle update --all
66
+ ACTIVE_RECORD_BRANCH=main bundle exec rake
67
+ ```
68
+
69
+ Style is enforced by [Standard](https://github.com/standardrb/standard), which
70
+ `rake` runs. To correct what it can:
71
+
72
+ ```sh
73
+ bundle exec standardrb --fix
74
+ ```
75
+
76
+ ## Changes and releases
77
+
78
+ Please add a line to `CHANGELOG.md` under `### Unreleased` describing your change
79
+ from the point of view of someone using the gem. Leave `lib/with_model/version.rb`
80
+ alone: version bumps and releases are cut separately by a maintainer, so a bump
81
+ in a pull request only creates a conflict.
82
+
83
+ Last, but not least, have fun.
data/Gemfile CHANGED
@@ -9,7 +9,6 @@ ar_version = ENV.fetch("ACTIVE_RECORD_VERSION", nil)
9
9
 
10
10
  if ar_branch
11
11
  gem "activerecord", git: "https://github.com/rails/rails.git", branch: ar_branch
12
- gem "arel", git: "https://github.com/rails/arel.git" if ar_branch == "master"
13
12
  elsif ar_version
14
13
  gem "activerecord", ar_version
15
14
  end
@@ -22,10 +21,6 @@ gem "minitest"
22
21
  gem "mutex_m"
23
22
  gem "rake"
24
23
  gem "rspec"
24
+ gem "ruby-lsp"
25
+ gem "sqlite3"
25
26
  gem "standard"
26
-
27
- if ar_branch == "7-0-stable" || ar_version == "~> 7.0.0"
28
- gem "sqlite3", "< 2"
29
- else
30
- gem "sqlite3"
31
- end
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010–2022 Casebook, PBC <http://www.casebook.net>
1
+ Copyright (c) 2010–2026 Casebook, PBC <http://www.casebook.net>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # [with_model](https://github.com/Casecommons/with_model)
2
2
 
3
3
  [![Gem Version](https://img.shields.io/gem/v/with_model.svg?style=flat)](https://rubygems.org/gems/with_model)
4
- [![Build Status](https://github.com/Casecommons/with_model/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Casecommons/with_model/actions/workflows/ci.yml)
4
+ [![Build Status](https://github.com/Casecommons/with_model/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Casecommons/with_model/actions/workflows/ci.yml?query=branch%3Amaster)
5
5
  [![API Documentation](https://img.shields.io/badge/yard-api%20docs-lightgrey.svg)](https://www.rubydoc.info/gems/with_model)
6
6
 
7
7
  `with_model` dynamically builds an Active Record model (with table) before each test in a group and destroys it afterwards.
@@ -19,7 +19,7 @@ Install as usual: `gem install with_model` or add `gem 'with_model'` to your Gem
19
19
  Extend `WithModel` into RSpec:
20
20
 
21
21
  ```ruby
22
- require 'with_model'
22
+ require "with_model"
23
23
 
24
24
  RSpec.configure do |config|
25
25
  config.extend WithModel
@@ -31,7 +31,7 @@ end
31
31
  Extend `WithModel` into minitest/spec and set the test runner explicitly:
32
32
 
33
33
  ```ruby
34
- require 'with_model'
34
+ require "with_model"
35
35
 
36
36
  WithModel.runner = :minitest
37
37
 
@@ -45,11 +45,16 @@ end
45
45
  After setting up as above, call `with_model` and inside its block pass it a `table` block and a `model` block.
46
46
 
47
47
  ```ruby
48
- require 'spec_helper'
48
+ require "spec_helper"
49
49
 
50
- describe "A blog post" do
51
- module MyModule; end
50
+ module MyModule; end
51
+
52
+ # A pre-existing model
53
+ class Car < ActiveRecord::Base
54
+ self.abstract_class = true
55
+ end
52
56
 
57
+ describe "A blog post" do
53
58
  with_model :BlogPost do
54
59
  # The table block (and an options hash) is passed to Active Record migration’s `create_table`.
55
60
  table do |t|
@@ -60,15 +65,16 @@ describe "A blog post" do
60
65
  # The model block is the Active Record model’s class body.
61
66
  model do
62
67
  include MyModule
68
+
63
69
  has_many :comments
64
70
  validates_presence_of :title
65
71
 
66
72
  def self.some_class_method
67
- 'chunky'
73
+ "chunky"
68
74
  end
69
75
 
70
76
  def some_instance_method
71
- 'bacon'
77
+ "bacon"
72
78
  end
73
79
  end
74
80
  end
@@ -91,15 +97,15 @@ describe "A blog post" do
91
97
  end
92
98
 
93
99
  it "has the module" do
94
- expect(BlogPost.include?(MyModule)).to eq true
100
+ expect(BlogPost.include?(MyModule)).to be true
95
101
  end
96
102
 
97
103
  it "has the class method" do
98
- expect(BlogPost.some_class_method).to eq 'chunky'
104
+ expect(BlogPost.some_class_method).to eq "chunky"
99
105
  end
100
106
 
101
107
  it "has the instance method" do
102
- expect(BlogPost.new.some_instance_method).to eq 'bacon'
108
+ expect(BlogPost.new.some_instance_method).to eq "bacon"
103
109
  end
104
110
 
105
111
  it "can do all the things a regular model can" do
@@ -107,22 +113,21 @@ describe "A blog post" do
107
113
  expect(record).not_to be_valid
108
114
  record.title = "foo"
109
115
  expect(record).to be_valid
110
- expect(record.save).to eq true
116
+ expect(record.save).to be true
111
117
  expect(record.reload).to eq record
112
- record.comments.create!(:text => "Lorem ipsum")
118
+ record.comments.create!(text: "Lorem ipsum")
113
119
  expect(record.comments.count).to eq 1
114
120
  end
115
121
 
116
- # with_model classes can have inheritance.
117
- class Car < ActiveRecord::Base
118
- self.abstract_class = true
119
- end
120
-
122
+ # with_model classes can have inheritance. Car is abstract, so it has no table
123
+ # and Ford gets one of its own. To inherit a concrete superclass's table
124
+ # instead, see "Single table inheritance" below.
121
125
  with_model :Ford, superclass: Car do
126
+ table
122
127
  end
123
128
 
124
129
  it "has a specified superclass" do
125
- expect(Ford < Car).to eq true
130
+ expect(Ford.new).to be_a(Car)
126
131
  end
127
132
  end
128
133
 
@@ -150,8 +155,8 @@ end
150
155
 
151
156
  describe "with table options" do
152
157
  with_model :WithOptions do
153
- table :id => false do |t|
154
- t.string 'foo'
158
+ table id: false do |t|
159
+ t.string "foo"
155
160
  t.timestamps null: false
156
161
  end
157
162
  end
@@ -162,6 +167,89 @@ describe "with table options" do
162
167
  end
163
168
  ```
164
169
 
170
+ ## Single table inheritance
171
+
172
+ Pass `table(false)` to create no table at all. Active Record's own inheritance
173
+ then supplies the superclass's table, which is what single table inheritance
174
+ needs.
175
+
176
+ The superclass can be another `with_model` model. Its constant does not exist yet
177
+ when the `superclass:` argument is read, so name it with a String or a Symbol, or
178
+ pass a callable returning it, and it will be resolved once per example.
179
+
180
+ ```ruby
181
+ describe "with_model supports Single Table Inheritance" do
182
+ with_model :Sandwich do
183
+ table do |t|
184
+ t.string "type"
185
+ t.string "bread"
186
+ end
187
+ end
188
+
189
+ with_model :ChunkyBacon, superclass: :Sandwich do
190
+ table(false)
191
+ end
192
+
193
+ it "shares the superclass's table" do
194
+ expect(ChunkyBacon.table_name).to eq Sandwich.table_name
195
+ end
196
+
197
+ it "stores its own type" do
198
+ sandwich = ChunkyBacon.create!(bread: "rye")
199
+
200
+ expect(sandwich.reload.type).to eq "ChunkyBacon"
201
+ expect(Sandwich.first).to be_a ChunkyBacon
202
+ end
203
+ end
204
+ ```
205
+
206
+ A `superclass:` that cannot be used raises `WithModel::InvalidSuperclass`: one
207
+ that is not an Active Record class, one with no table of its own
208
+ (`ActiveRecord::Base`, or an abstract class such as a Rails app's
209
+ `ApplicationRecord`), or one whose table has no inheritance column to tell a
210
+ subclass's rows apart. A name that resolves to nothing raises
211
+ `WithModel::MissingSuperclass`, a kind of `InvalidSuperclass`, quoting the
212
+ constant Ruby could not find — for a namespaced name, that is the segment which
213
+ is actually missing. Both are `ArgumentError`s.
214
+
215
+ A superclass whose table does not exist *yet* is allowed, since the table may be
216
+ created later in the example, and Active Record reports its absence clearly
217
+ enough on its own. Rows the model wrote are deleted when it goes away, since they
218
+ name a class that is about to stop existing and would make the superclass
219
+ unloadable.
220
+
221
+ ## Foreign keys
222
+
223
+ `foreign_key: true` asks Active Record to infer the table a foreign key points
224
+ at, and it infers `authors` from `author_id`. Generated table names are unique
225
+ rather than conventional, so name the table instead:
226
+
227
+ ```ruby
228
+ describe "with_model supports foreign keys" do
229
+ with_model :Author do
230
+ table
231
+ end
232
+
233
+ with_model :Book do
234
+ table do |t|
235
+ t.references :author, foreign_key: {to_table: Author.table_name}
236
+ end
237
+
238
+ model do
239
+ belongs_to :author
240
+ end
241
+ end
242
+
243
+ it "has a foreign key" do
244
+ expect { Book.create!(author_id: 0) }
245
+ .to raise_error ActiveRecord::InvalidForeignKey
246
+ end
247
+ end
248
+ ```
249
+
250
+ This reads `Author.table_name`, so declare `Author` first: models are created in
251
+ the order they are declared, and destroyed in the reverse order.
252
+
165
253
  ## Requirements
166
254
 
167
255
  See the [gemspec metadata](https://rubygems.org/gems/with_model) for dependency requirements. RSpec and minitest are indirect dependencies, and `with_model` should support any maintained version of both.
@@ -177,11 +265,17 @@ See the [gemspec metadata](https://rubygems.org/gems/with_model) for dependency
177
265
 
178
266
  In general, `with_model` is not guaranteed to be thread-safe, but is, in certain usages, safe to use concurrently across multiple processes with a single database schema.
179
267
 
268
+ ## Contributing
269
+
270
+ Bug reports and pull requests are welcome. See the
271
+ [CONTRIBUTING guide](/CONTRIBUTING.md) for how to run the tests against a
272
+ particular Ruby or Active Record.
273
+
180
274
  ## Versioning
181
275
 
182
276
  `with_model` uses [Semantic Versioning 2.0.0](http://semver.org/spec/v2.0.0.html).
183
277
 
184
278
  ## License
185
279
 
186
- Copyright © 2010–2022 [Casebook PBC](https://www.casebook.net).
280
+ Copyright © 2010–2026 [Casebook PBC](https://www.casebook.net).
187
281
  Licensed under the MIT license, see [LICENSE](/LICENSE) file.
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WithModel
4
+ # Raised when the `superclass:` a model was given cannot be used: it is not an
5
+ # Active Record class at all, or it is one that cannot supply a table to a model
6
+ # which has none of its own - because it has no table itself
7
+ # (`ActiveRecord::Base`, or an abstract class), or because its table has no
8
+ # inheritance column and so cannot tell a subclass's rows apart.
9
+ #
10
+ # An `ArgumentError`, because each is a fact about the argument rather than about
11
+ # when it was looked at, and the superclass is needed the moment the model is
12
+ # built - unlike a table, which an example is free to create later.
13
+ class InvalidSuperclass < ArgumentError
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "with_model/invalid_superclass"
4
+
5
+ module WithModel
6
+ # Raised when the name given for a `superclass:` resolves to nothing at all.
7
+ #
8
+ # A kind of {WithModel::InvalidSuperclass}, so every superclass that cannot be
9
+ # used is catchable in one place, while a name that is simply not there - a
10
+ # typo, or a with_model superclass declared after the models inheriting it -
11
+ # can be told apart from a class that exists but cannot supply a table.
12
+ class MissingSuperclass < InvalidSuperclass
13
+ end
14
+ end
@@ -11,10 +11,13 @@ module WithModel
11
11
  # Provide a schema definition for the table, passed to ActiveRecord's `create_table`.
12
12
  # The table name will be auto-generated.
13
13
  #
14
+ # Pass `false` instead of options to create no table at all, so that the
15
+ # model inherits its superclass's table as Rails Single Table Inheritance
16
+ # requires. `table(false)` takes no block.
17
+ #
14
18
  # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-create_table
15
19
  def table(options = {}, &block)
16
- @model.table_options = options
17
- @model.table_block = block
20
+ @model.specify_table(options, block)
18
21
  end
19
22
 
20
23
  # Provide a class body for the ActiveRecord model.