Class: DeclareSchema::Model::HabtmModelShim
- Inherits:
-
Object
- Object
- DeclareSchema::Model::HabtmModelShim
- Defined in:
- lib/declare_schema/model/habtm_model_shim.rb
Instance Attribute Summary collapse
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
-
#foreign_keys ⇒ Object
readonly
Returns the value of attribute foreign_keys.
-
#join_table ⇒ Object
readonly
Returns the value of attribute join_table.
-
#parent_models ⇒ Object
readonly
Returns the value of attribute parent_models.
-
#parent_table_names ⇒ Object
readonly
Returns the value of attribute parent_table_names.
Class Method Summary collapse
Instance Method Summary collapse
- #_declared_primary_key ⇒ Object
- #_table_options ⇒ Object
-
#columns_hash ⇒ Object
Mirror the AR class API for ‘model.columns_hash` so the migrator’s change_column_back / add_column_back paths work uniformly across real AR models and HABTM shims.
- #constraint_definitions ⇒ Object
- #field_specs ⇒ Object
- #ignore_indexes ⇒ Object
- #index_definitions ⇒ Object
- #index_definitions_with_primary_key ⇒ Object
-
#initialize(join_table, parents, connection:) ⇒ HabtmModelShim
constructor
A new instance of HabtmModelShim.
-
#primary_key ⇒ Object
The HABTM join table’s primary key is the composite of its two foreign keys.
- #table_name ⇒ Object
-
#table_name=(new_table_name) ⇒ Object
The migrator (in change_column_back / add_column_back / etc.) wraps column introspection in ‘with_previous_model_table_name`, which expects a model that exposes `table_name=`.
Constructor Details
#initialize(join_table, parents, connection:) ⇒ HabtmModelShim
Returns a new instance of HabtmModelShim.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 19 def initialize(join_table, parents, connection:) @join_table = join_table parents.is_a?(Array) && parents.size == 2 or raise ArgumentError, "parents must be <Array[2]>; got #{parents.inspect}" # Rails requires HABTM foreign keys to be in alphabetical order, so we start by sorting by those parents.sort_by!(&:first) @foreign_keys = parents.map(&:first) @parent_models = parents.map(&:last) @parent_table_names = parent_models.map(&:table_name) @connection = connection end |
Instance Attribute Details
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
17 18 19 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 17 def connection @connection end |
#foreign_keys ⇒ Object (readonly)
Returns the value of attribute foreign_keys.
17 18 19 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 17 def foreign_keys @foreign_keys end |
#join_table ⇒ Object (readonly)
Returns the value of attribute join_table.
17 18 19 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 17 def join_table @join_table end |
#parent_models ⇒ Object (readonly)
Returns the value of attribute parent_models.
17 18 19 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 17 def parent_models @parent_models end |
#parent_table_names ⇒ Object (readonly)
Returns the value of attribute parent_table_names.
17 18 19 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 17 def parent_table_names @parent_table_names end |
Class Method Details
.from_reflection(reflection) ⇒ Object
7 8 9 10 11 12 13 14 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 7 def from_reflection(reflection) new(reflection.join_table, [ [reflection.foreign_key, reflection.active_record], [reflection.association_foreign_key, reflection.klass] ], connection: reflection.active_record.connection) end |
Instance Method Details
#_declared_primary_key ⇒ Object
80 81 82 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 80 def _declared_primary_key foreign_keys end |
#_table_options ⇒ Object
34 35 36 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 34 def {} end |
#columns_hash ⇒ Object
Mirror the AR class API for ‘model.columns_hash` so the migrator’s change_column_back / add_column_back paths work uniformly across real AR models and HABTM shims. Backed by ‘connection.columns(table_name)` rather than AR’s class-level cache because the shim has no class-level cache.
55 56 57 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 55 def columns_hash connection.columns(table_name).index_by(&:name) end |
#constraint_definitions ⇒ Object
101 102 103 104 105 106 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 101 def constraint_definitions @constraint_definitions ||= Set.new([ ForeignKeyDefinition.new(foreign_keys.first, constraint_name: "#{join_table}_FK1", child_table_name: @join_table, parent_table_name: parent_table_names.first, dependent: :delete), ForeignKeyDefinition.new(foreign_keys.last, constraint_name: "#{join_table}_FK2", child_table_name: @join_table, parent_table_name: parent_table_names.last, dependent: :delete) ]) end |
#field_specs ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 59 def field_specs foreign_keys.each_with_index.each_with_object({}) do |(foreign_key, i), result| parent_model = parent_models[i] result[foreign_key] = if parent_model.respond_to?(:_foreign_key_field_spec) # declare_schema model: mirror the parent's primary key (type, limit, etc.) parent_model._foreign_key_field_spec(self, foreign_key, position: i, null: false) else # Non-declare_schema parent: fall back to the configured default PK type. ::DeclareSchema::Model::FieldSpec.new(self, foreign_key, ::DeclareSchema.default_generated_primary_key_type, position: i, null: false) end end end |
#ignore_indexes ⇒ Object
97 98 99 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 97 def ignore_indexes @ignore_indexes ||= Set.new end |
#index_definitions ⇒ Object
84 85 86 87 88 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 84 def index_definitions [ IndexDefinition.new(foreign_keys.last, table_name: table_name, unique: false) # index for queries where we only have the last foreign key ] end |
#index_definitions_with_primary_key ⇒ Object
90 91 92 93 94 95 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 90 def index_definitions_with_primary_key [ *index_definitions, IndexDefinition.new(foreign_keys, table_name: table_name, name: Model::IndexDefinition::PRIMARY_KEY_NAME, unique: true) # creates a primary composite key on both foreign keys ] end |
#primary_key ⇒ Object
The HABTM join table’s primary key is the composite of its two foreign keys. (Rails 7.1+ supports composite PKs natively; on 7.0 nothing in AR introspects this shim, so returning an Array is safe for our callers.)
76 77 78 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 76 def primary_key foreign_keys end |
#table_name ⇒ Object
38 39 40 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 38 def table_name join_table end |
#table_name=(new_table_name) ⇒ Object
The migrator (in change_column_back / add_column_back / etc.) wraps column introspection in ‘with_previous_model_table_name`, which expects a model that exposes `table_name=`. Real AR classes do; this shim doesn’t keep AR-style cached metadata keyed on table_name, so we just rewrite @join_table – the only state our ‘table_name` reads.
47 48 49 |
# File 'lib/declare_schema/model/habtm_model_shim.rb', line 47 def table_name=(new_table_name) @join_table = new_table_name end |