exwiw 0.2.6 → 0.2.8

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: 2ff943aae77c0ed0f79dc80c2e68527badcae7c6b330e89aec6a019adf0dd1e5
4
- data.tar.gz: 8a146a76aea7ab0bd3aeabb27ccf789f575f86e1d965b64b2432c250addb003b
3
+ metadata.gz: 21a9432692220a23b0109497b0ffcb3f1c7f0fc360248c3590f730a4a98452ec
4
+ data.tar.gz: bf0847f90a24c8da3cf078f1c18e5d22f9827b705bc13945ddfc28f8e42460f1
5
5
  SHA512:
6
- metadata.gz: 6dbd0212c4ca02aba3839f17bfe7fc45283f17cb7264d903527fbafda04a4cc9b5c756762a1422fae549b143a60ec825669581311ada63972c2288bdb744e47c
7
- data.tar.gz: 6364942e8ee51055eb2ed2bffc16995b1a19c64b977790fa8ff4222742f034ae6d4b0b7410f779f70655bb2d6d3ea33af7321853727a2c9300adcdcbd45fc763
6
+ metadata.gz: c59e201f1180e2fb6191506647b78a82c43d7d124117c0d87e2cdcbfd8fa68ff30653accc9a22d82434d7e680496eed41d91c7b150b8b884b3b545b344b91d72
7
+ data.tar.gz: 600e4a3b8d134d43182b81017b8b4ad9a352824a76a351300ca3fc22ee4942ceccf6f8404eb6e04e2a2320a79849ddc6b3cacf0c3510c7b8acca0c06820eaa22
data/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.2.8] - 2026-05-31
6
+
7
+ ### Added
8
+
9
+ - `schema:generate` now supports polymorphic `belongs_to` associations. Each polymorphic relation (`belongs_to :reviewable, polymorphic: true`) is expanded into one `belongs_to` entry per concrete target table — discovered from the other models' `has_many` / `has_one ..., as:` declarations — carrying `foreign_type` (the type column, e.g. `reviewable_type`) and `type_value` (the stored type, e.g. `"Product"`). Targets are ordered by table name so the generated output is stable across Ruby versions. At dump time, a polymorphic `belongs_to` on the path to the dump target is constrained by both the foreign key and the type column — in both the `SELECT` and the `delete-*.sql` bulk-delete subquery — so only rows of the matching type are extracted. ([#43](https://github.com/heyinc/exwiw/pull/43))
10
+
11
+ ## [0.2.7] - 2026-05-30
12
+
13
+ ### Added
14
+
15
+ - `schema:generate` no longer crashes on models with a composite primary key (`primary_key` returns an Array). Such tables are emitted with `skip: true`, tagged `type: "unsupported_composite_primary_key"`, and annotated with a `comment` listing the key columns. `columns` / `belongs_tos` are retained so the entry can be wired up once composite-key support lands; for now `skip: true` excludes it from extraction. `skip: true` tables no longer require `primary_key` at load time.
16
+
17
+ ### Notes
18
+
19
+ - `schema:generate` multi-database support: each database keeps its own Rails migration history, so a per-database `schema_migrations` / `ar_internal_metadata` entry is emitted for every database that has one. Known limitation: the rails-managed table *name* is resolved from the global `ActiveRecord::Base.schema_migrations_table_name` / `internal_metadata_table_name` accessors, so a per-database override of those names is not detected and the table will be missing from that database's generated configs.
20
+
5
21
  ## [0.2.6] - 2026-05-29
6
22
 
7
23
  ### Added
data/README.md CHANGED
@@ -142,7 +142,11 @@ exwiw/
142
142
  analytics_events.json
143
143
  ```
144
144
 
145
- Rails-managed tables (`schema_migrations` / `ar_internal_metadata`) are emitted under whichever database actually contains them. Single-database applications are unaffected and continue to write files flat into the output directory.
145
+ Each database keeps its own Rails migration history, so a `schema_migrations` (and `ar_internal_metadata`) entry is emitted under every database that contains one — the example above shows `primary/schema_migrations.json` and would also produce `analytics/schema_migrations.json` when the analytics database has its own migration table. Single-database applications are unaffected and continue to write files flat into the output directory.
146
+
147
+ **Limitations**
148
+
149
+ - The rails-managed table *names* are resolved from the global `ActiveRecord::Base.schema_migrations_table_name` / `internal_metadata_table_name` accessors, which are shared across all connections. A per-database override of these names is not detected, so such a table will be missing from that database's generated configs.
146
150
 
147
151
  ### Configuration
148
152
 
@@ -237,6 +241,47 @@ Constraints:
237
241
  - Specifying a skipped table as `--target-table` raises `ArgumentError`.
238
242
  - `skip: true` is preserved by `exwiw:schema:generate` regenerations (the receiver value wins over the auto-generated config).
239
243
 
244
+ ### Polymorphic `belongs_to`
245
+
246
+ A Rails polymorphic association (`belongs_to :reviewable, polymorphic: true`) does not point at a single table — the target row is selected at runtime by a type column. exwiw models this as **one `belongs_to` entry per concrete target table**, each carrying two extra fields:
247
+
248
+ - `foreign_type` — the type column on *this* table (e.g. `reviewable_type`).
249
+ - `type_value` — the value stored in that column for this target (e.g. `"Product"`), i.e. the target model's `polymorphic_name`.
250
+
251
+ ```json
252
+ {
253
+ "name": "reviews",
254
+ "primary_key": "id",
255
+ "belongs_tos": [
256
+ {
257
+ "table_name": "products",
258
+ "foreign_key": "reviewable_id",
259
+ "foreign_type": "reviewable_type",
260
+ "type_value": "Product"
261
+ },
262
+ {
263
+ "table_name": "shops",
264
+ "foreign_key": "reviewable_id",
265
+ "foreign_type": "reviewable_type",
266
+ "type_value": "Shop"
267
+ }
268
+ ],
269
+ "columns": [{ "name": "id" }, { "name": "reviewable_type" }, { "name": "reviewable_id" }]
270
+ }
271
+ ```
272
+
273
+ `exwiw:schema:generate` expands a polymorphic `belongs_to` automatically: it finds every model that registers the association as a target via `has_many` / `has_one ..., as: :reviewable` and emits one entry per target table (ordered by table name so the output is stable across Ruby versions). A plain (non-polymorphic) `belongs_to` simply omits `foreign_type` / `type_value`.
274
+
275
+ At dump time, when a polymorphic `belongs_to` lies on the path to the dump target, exwiw constrains **both** the foreign key and the type column, so only rows of the matching type are extracted. For example, dumping `products` pulls only reviews whose `reviewable_type = 'Product'`:
276
+
277
+ ```sql
278
+ SELECT reviews.* FROM reviews
279
+ WHERE reviews.reviewable_id IN (/* products subquery */)
280
+ AND reviews.reviewable_type = 'Product'
281
+ ```
282
+
283
+ The same type filter is applied on the join path — and in the matching `delete-*.sql` bulk-delete subquery — when the polymorphic table is an intermediate hop rather than the directly-dumped table.
284
+
240
285
  ### Rails-managed tables (special `type` values)
241
286
 
242
287
  Some tables are owned by Rails itself rather than the application — they have no ActiveRecord model and Rails reserves the right to evolve their column shape between versions (e.g. `schema_migrations`, `ar_internal_metadata`). exwiw treats them as a distinct category via the `type` field on a table config:
@@ -268,6 +313,23 @@ Constraints:
268
313
  - A rails-managed table cannot be used as `--target-table`.
269
314
  - In multi-database setups, the rails-managed entry is emitted under whichever database's connection actually contains the table (see [Multiple databases](#multiple-databases)). The table name itself is still derived from the global `ActiveRecord::Base.schema_migrations_table_name` / `internal_metadata_table_name` (prefix/suffix) accessors.
270
315
 
316
+ ### Composite primary keys (unsupported)
317
+
318
+ exwiw does not yet support tables with a composite primary key. When `exwiw:schema:generate` encounters a model whose `primary_key` is an array, it still emits a config entry so the table is not silently dropped, but marks it `skip: true`, tags it `type: "unsupported_composite_primary_key"`, and records the key columns in a `comment`:
319
+
320
+ ```json
321
+ {
322
+ "name": "composite_pk_records",
323
+ "type": "unsupported_composite_primary_key",
324
+ "skip": true,
325
+ "comment": "exwiw does not support composite primary keys (organization_id, location_id); data extraction is skipped.",
326
+ "belongs_tos": [],
327
+ "columns": [{ "name": "organization_id" }, { "name": "location_id" }, { "name": "name" }]
328
+ }
329
+ ```
330
+
331
+ Unlike rails-managed entries, `columns` and `belongs_tos` are retained so the entry is ready to wire up once composite-key support lands. The `type` is purely a marker — `skip: true` is what actually excludes the table from extraction, so removing `skip` (and supplying a workable `primary_key`) lets you opt the table back in manually.
332
+
271
333
  ### Bulk insert chunk size
272
334
 
273
335
  `bulk_insert_chunk_size` splits the generated `INSERT` statement into multiple statements, each containing at most the specified number of rows. This is useful when the number of records per table is large enough to hit limits like MySQL's `max_allowed_packet`.
@@ -136,7 +136,18 @@ module Exwiw
136
136
 
137
137
  foreign_key = first_join.foreign_key
138
138
  subquery_sql = compile_ast(subquery_ast)
139
- sql += "\nWHERE #{select_query_ast.from_table_name}.#{foreign_key} IN (#{subquery_sql});"
139
+ sql += "\nWHERE #{select_query_ast.from_table_name}.#{foreign_key} IN (#{subquery_sql})"
140
+
141
+ # first_join.base_where_clauses は外側の削除対象テーブル
142
+ # (from_table_name) 上の条件 (polymorphic 型カラム等)。subquery には
143
+ # 含まれないため、外側の WHERE に追加する。これにより、別の
144
+ # polymorphic 型に属する行まで削除してしまうのを防ぐ。
145
+ first_join.base_where_clauses.each do |where|
146
+ next unless where.is_a?(Exwiw::QueryAst::WhereClause)
147
+
148
+ sql += " AND #{compile_where_condition(where, select_query_ast.from_table_name)}"
149
+ end
150
+ sql += ";"
140
151
 
141
152
  sql
142
153
  end
@@ -159,6 +170,13 @@ module Exwiw
159
170
  compiled_where_condition = compile_where_condition(where, join.join_table_name)
160
171
  sql += " AND #{compiled_where_condition}"
161
172
  end
173
+
174
+ # base_where_clauses は結合元テーブル (base_table_name) に対して
175
+ # コンパイルする。polymorphic な結合元テーブルの型カラム絞り込み等。
176
+ join.base_where_clauses.each do |where|
177
+ compiled_where_condition = compile_where_condition(where, join.base_table_name)
178
+ sql += " AND #{compiled_where_condition}"
179
+ end
162
180
  end
163
181
 
164
182
  if query_ast.where_clauses.any?
@@ -178,7 +178,18 @@ module Exwiw
178
178
 
179
179
  foreign_key = first_join.foreign_key
180
180
  subquery_sql = compile_ast(subquery_ast)
181
- sql += "\nWHERE #{select_query_ast.from_table_name}.#{foreign_key} IN (#{subquery_sql});"
181
+ sql += "\nWHERE #{select_query_ast.from_table_name}.#{foreign_key} IN (#{subquery_sql})"
182
+
183
+ # first_join.base_where_clauses は外側の削除対象テーブル
184
+ # (from_table_name) 上の条件 (polymorphic 型カラム等)。subquery には
185
+ # 含まれないため、外側の WHERE に追加する。これにより、別の
186
+ # polymorphic 型に属する行まで削除してしまうのを防ぐ。
187
+ first_join.base_where_clauses.each do |where|
188
+ next unless where.is_a?(Exwiw::QueryAst::WhereClause)
189
+
190
+ sql += " AND #{compile_where_condition(where, select_query_ast.from_table_name)}"
191
+ end
192
+ sql += ";"
182
193
 
183
194
  sql
184
195
  end
@@ -201,6 +212,13 @@ module Exwiw
201
212
  compiled_where_condition = compile_where_condition(where, join.join_table_name)
202
213
  sql += " AND #{compiled_where_condition}"
203
214
  end
215
+
216
+ # base_where_clauses は結合元テーブル (base_table_name) に対して
217
+ # コンパイルする。polymorphic な結合元テーブルの型カラム絞り込み等。
218
+ join.base_where_clauses.each do |where|
219
+ compiled_where_condition = compile_where_condition(where, join.base_table_name)
220
+ sql += " AND #{compiled_where_condition}"
221
+ end
204
222
  end
205
223
 
206
224
  if query_ast.where_clauses.any?
@@ -123,7 +123,18 @@ module Exwiw
123
123
 
124
124
  foreign_key = first_join.foreign_key
125
125
  subquery_sql = compile_ast(subquery_ast)
126
- sql += "\nWHERE #{select_query_ast.from_table_name}.#{foreign_key} IN (#{subquery_sql});"
126
+ sql += "\nWHERE #{select_query_ast.from_table_name}.#{foreign_key} IN (#{subquery_sql})"
127
+
128
+ # first_join.base_where_clauses は外側の削除対象テーブル
129
+ # (from_table_name) 上の条件 (polymorphic 型カラム等)。subquery には
130
+ # 含まれないため、外側の WHERE に追加する。これにより、別の
131
+ # polymorphic 型に属する行まで削除してしまうのを防ぐ。
132
+ first_join.base_where_clauses.each do |where|
133
+ next unless where.is_a?(Exwiw::QueryAst::WhereClause)
134
+
135
+ sql += " AND #{compile_where_condition(where, select_query_ast.from_table_name)}"
136
+ end
137
+ sql += ";"
127
138
 
128
139
  sql
129
140
  end
@@ -146,6 +157,13 @@ module Exwiw
146
157
  compiled_where_condition = compile_where_condition(where, join.join_table_name)
147
158
  sql += " AND #{compiled_where_condition}"
148
159
  end
160
+
161
+ # base_where_clauses は結合元テーブル (base_table_name) に対して
162
+ # コンパイルする。polymorphic な結合元テーブルの型カラム絞り込み等。
163
+ join.base_where_clauses.each do |where|
164
+ compiled_where_condition = compile_where_condition(where, join.base_table_name)
165
+ sql += " AND #{compiled_where_condition}"
166
+ end
149
167
  end
150
168
 
151
169
  if query_ast.where_clauses.any?
@@ -6,9 +6,22 @@ module Exwiw
6
6
 
7
7
  attribute :foreign_key, String
8
8
  attribute :table_name, String
9
+ # polymorphic 関連の場合のみ設定される。`foreign_type` は型を格納するカラム名
10
+ # (例: `reviewable_type`)、`type_value` はそのカラムに入る値 (例: `"Product"`)。
11
+ # 非 polymorphic の belongs_to では両方とも nil。
12
+ attribute :foreign_type, optional(String), skip_serializing_if_nil: true
13
+ attribute :type_value, optional(String), skip_serializing_if_nil: true
9
14
 
10
15
  def self.from_symbol_keys(hash)
11
16
  from(hash.transform_keys(&:to_s))
12
17
  end
18
+
19
+ def polymorphic?
20
+ !foreign_type.nil?
21
+ end
22
+
23
+ def to_hash
24
+ super.compact
25
+ end
13
26
  end
14
27
  end
@@ -3,14 +3,20 @@
3
3
  module Exwiw
4
4
  module QueryAst
5
5
  class JoinClause
6
- attr_reader :base_table_name, :foreign_key, :join_table_name, :primary_key, :where_clauses
6
+ # `where_clauses` はこの join の join_table_name (= 結合先テーブル) に対して
7
+ # コンパイルされる。一方 `base_where_clauses` は base_table_name (= 結合元
8
+ # テーブル) に対してコンパイルされる。後者は、結合元テーブルが結合先へ
9
+ # polymorphic belongs_to していて型カラム (foreign_type) が結合元テーブル
10
+ # 側に存在するケースのために使う。
11
+ attr_reader :base_table_name, :foreign_key, :join_table_name, :primary_key, :where_clauses, :base_where_clauses
7
12
 
8
- def initialize(base_table_name:, foreign_key:, join_table_name:, primary_key:, where_clauses: [])
13
+ def initialize(base_table_name:, foreign_key:, join_table_name:, primary_key:, where_clauses: [], base_where_clauses: [])
9
14
  @base_table_name = base_table_name
10
15
  @foreign_key = foreign_key
11
16
  @join_table_name = join_table_name
12
17
  @primary_key = primary_key
13
18
  @where_clauses = where_clauses
19
+ @base_where_clauses = base_where_clauses
14
20
  end
15
21
 
16
22
  def to_h
@@ -23,6 +29,9 @@ module Exwiw
23
29
  if where_clauses.size.positive?
24
30
  hash[:where_clauses] = where_clauses.map { |wc| wc.is_a?(String) ? wc : wc.to_h }
25
31
  end
32
+ if base_where_clauses.size.positive?
33
+ hash[:base_where_clauses] = base_where_clauses.map { |wc| wc.is_a?(String) ? wc : wc.to_h }
34
+ end
26
35
  hash
27
36
  end
28
37
  end
@@ -54,8 +54,23 @@ module Exwiw
54
54
  foreign_key: relation.foreign_key,
55
55
  join_table_name: to_table.name,
56
56
  primary_key: to_table.primary_key,
57
- where_clauses: []
57
+ where_clauses: [],
58
+ base_where_clauses: []
58
59
  )
60
+
61
+ # この hop 自体が polymorphic belongs_to の場合 (例: comments が
62
+ # commentable として posts へ polymorphic belongs_to)、型カラム
63
+ # (foreign_type) は結合元テーブル (from_table = base_table_name) 側に
64
+ # 存在する。外部キーだけでは reviewable_id=1 のような値が別モデルの
65
+ # 行と衝突しうるため、base_where_clauses に型条件を追加して結合元
66
+ # テーブルを絞り込む。
67
+ if relation.polymorphic?
68
+ join_clause.base_where_clauses.push QueryAst::WhereClause.new(
69
+ column_name: relation.foreign_type,
70
+ operator: :eq,
71
+ value: [relation.type_value]
72
+ )
73
+ end
59
74
  relation_to_dump_target = to_table.belongs_to(dump_target.table_name)
60
75
  if relation_to_dump_target
61
76
  join_clause.where_clauses.push QueryAst::WhereClause.new(
@@ -63,6 +78,18 @@ module Exwiw
63
78
  operator: :eq,
64
79
  value: dump_target.ids
65
80
  )
81
+
82
+ # 中間テーブルが dump target へ polymorphic belongs_to している場合は、
83
+ # 型カラム (foreign_type) も join 条件に追加する。型カラムは to_table
84
+ # (= join_table_name) 上に存在するため、JoinClause の where_clauses が
85
+ # join_table_name に対してコンパイルされる仕組みにそのまま乗せられる。
86
+ if relation_to_dump_target.polymorphic?
87
+ join_clause.where_clauses.push QueryAst::WhereClause.new(
88
+ column_name: relation_to_dump_target.foreign_type,
89
+ operator: :eq,
90
+ value: [relation_to_dump_target.type_value]
91
+ )
92
+ end
66
93
  end
67
94
 
68
95
  # Add filter from intermediate table to join clause
@@ -98,6 +125,17 @@ module Exwiw
98
125
  value: dump_target.ids
99
126
  )
100
127
 
128
+ # polymorphic belongs_to の場合は外部キーだけでは型を区別できないため
129
+ # (例: reviewable_id=1 が Product なのか別モデルなのか判別できない)、
130
+ # 型カラム (foreign_type) を type_value で絞り込む条件を追加する。
131
+ if belongs_to.polymorphic?
132
+ clauses.push Exwiw::QueryAst::WhereClause.new(
133
+ column_name: belongs_to.foreign_type,
134
+ operator: :eq,
135
+ value: [belongs_to.type_value]
136
+ )
137
+ end
138
+
101
139
  if table.filter
102
140
  clauses.push table.filter
103
141
  end
@@ -76,12 +76,31 @@ module Exwiw
76
76
  private def build_tables_for(models, conn)
77
77
  tables_from_models = models.group_by(&:table_name).map do |table_name, model_group|
78
78
  representative = model_group.first
79
- TableConfig.from_symbol_keys(
80
- name: table_name,
81
- primary_key: representative.primary_key,
82
- belongs_tos: aggregate_belongs_tos(model_group),
83
- columns: representative.column_names.map { |name| { name: name } },
84
- )
79
+ primary_key = representative.primary_key
80
+
81
+ # 複合主キー (`representative.primary_key` が Array) のテーブルは現状未対応。
82
+ # primary_key を省略し、type で非対応である旨を明示したうえで skip:true
83
+ # 付与して出力する。type を付けておくことで将来対応する際の目印になる。
84
+ # 利用者が必要に応じて手動で skip を外して設定し直せるよう、設定ファイル
85
+ # 自体は生成しておく。
86
+ if primary_key.is_a?(Array)
87
+ TableConfig.from_symbol_keys(
88
+ name: table_name,
89
+ type: TableConfig::UNSUPPORTED_COMPOSITE_PRIMARY_KEY,
90
+ skip: true,
91
+ comment: "exwiw does not support composite primary keys " \
92
+ "(#{primary_key.join(', ')}); data extraction is skipped.",
93
+ belongs_tos: aggregate_belongs_tos(model_group),
94
+ columns: representative.column_names.map { |name| { name: name } },
95
+ )
96
+ else
97
+ TableConfig.from_symbol_keys(
98
+ name: table_name,
99
+ primary_key: primary_key,
100
+ belongs_tos: aggregate_belongs_tos(model_group),
101
+ columns: representative.column_names.map { |name| { name: name } },
102
+ )
103
+ end
85
104
  end
86
105
 
87
106
  tables_from_models + build_rails_managed_tables(conn)
@@ -126,15 +145,44 @@ module Exwiw
126
145
  end
127
146
 
128
147
  private def aggregate_belongs_tos(models)
129
- pairs = models
130
- .flat_map { |m| m.reflect_on_all_associations(:belongs_to) }
131
- .reject(&:polymorphic?) # XXX: Support polymorphic
132
- .map { |assoc| [assoc.table_name, assoc.foreign_key] }
133
- .uniq
134
-
135
- pairs.map do |table_name, foreign_key|
136
- { table_name: table_name, foreign_key: foreign_key }
137
- end
148
+ belongs_to_assocs = models.flat_map { |m| m.reflect_on_all_associations(:belongs_to) }
149
+
150
+ non_polymorphic = belongs_to_assocs
151
+ .reject(&:polymorphic?)
152
+ .map { |assoc| { table_name: assoc.table_name, foreign_key: assoc.foreign_key } }
153
+
154
+ # polymorphic な belongs_to (`belongs_to :reviewable, polymorphic: true`) は
155
+ # 単一の対象テーブルを持たない。対象になりうるテーブルは、他モデルで
156
+ # `has_many/has_one ..., as: <association_name>` と宣言されている側から逆引き
157
+ # する。各候補テーブルごとに、型カラム (`foreign_type`) と格納される型の値
158
+ # (`type_value`) を添えた belongs_to を 1 件ずつ展開する。
159
+ polymorphic = belongs_to_assocs
160
+ .select(&:polymorphic?)
161
+ .flat_map do |assoc|
162
+ polymorphic_target_models(assoc.name).map do |target_model|
163
+ {
164
+ table_name: target_model.table_name,
165
+ foreign_key: assoc.foreign_key,
166
+ foreign_type: assoc.foreign_type,
167
+ type_value: target_model.polymorphic_name,
168
+ }
169
+ end
170
+ end
171
+
172
+ (non_polymorphic + polymorphic).uniq
173
+ end
174
+
175
+ # polymorphic 関連 `association_name` の対象となりうる具象モデルを、全モデルの
176
+ # `has_many` / `has_one` の `as:` オプションから逆引きして列挙する。
177
+ # `concrete_models` の並びは `ActiveRecord::Base.descendants` の順に依存し、
178
+ # Ruby バージョンによって変わりうるため、生成される belongs_to の並びが安定する
179
+ # よう `table_name` でソートして決定的に返す。
180
+ private def polymorphic_target_models(association_name)
181
+ concrete_models.select do |model|
182
+ (model.reflect_on_all_associations(:has_many) +
183
+ model.reflect_on_all_associations(:has_one))
184
+ .any? { |reflection| reflection.options[:as] == association_name }
185
+ end.sort_by(&:table_name)
138
186
  end
139
187
 
140
188
  # Identifies which database a model belongs to. With Rails multi-DB
@@ -11,6 +11,11 @@ module Exwiw
11
11
  RAILS_MANAGED_INTERNAL_METADATA,
12
12
  ].freeze
13
13
 
14
+ # exwiw が現状サポートしていない複合主キーのテーブルを表す type。
15
+ # schema:generate が skip:true と併せて付与する。将来サポートする際の
16
+ # 目印になるよう、rails-managed とは異なり columns/belongs_tos は保持する。
17
+ UNSUPPORTED_COMPOSITE_PRIMARY_KEY = "unsupported_composite_primary_key"
18
+
14
19
  attribute :name, String
15
20
  attribute :primary_key, optional(String), skip_serializing_if_nil: true
16
21
  attribute :type, optional(String), skip_serializing_if_nil: true
@@ -138,7 +143,9 @@ module Exwiw
138
143
  "Table '#{name}' has type=#{type}; columns must not be defined."
139
144
  end
140
145
  else
141
- if primary_key.nil?
146
+ # skip:true のテーブルはデータ抽出を行わないため primary_key を要求しない。
147
+ # (例: exwiw 非対応の複合主キーテーブル)
148
+ if primary_key.nil? && !skip
142
149
  raise ArgumentError, "Table '#{name}' requires primary_key."
143
150
  end
144
151
  end
data/lib/exwiw/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Exwiw
4
- VERSION = "0.2.6"
4
+ VERSION = "0.2.8"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exwiw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shia