Skip to content

Commit c81a58a

Browse files
authored
Add support for Rails 8.1 (#203)
1 parent 2aa4cd1 commit c81a58a

File tree

3 files changed

+40
-18
lines changed

3 files changed

+40
-18
lines changed

app/controllers/motor/data_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def execute
8181

8282
def resource_params
8383
if params[:data].present?
84+
# Allow all attributes through; dynamic model class limits what is actually persisted
8485
params.require(:data).permit!
8586
else
8687
{}

lib/motor/configs/sync_from_file.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ def call(with_exception: false)
2323

2424
next unless file_timestamp
2525

26-
FILE_TIMESTAMPS_STORE.fetch(file_timestamp.to_s) do
26+
cache_key = file_timestamp.to_s
27+
28+
unless FILE_TIMESTAMPS_STORE.exist?(cache_key)
2729
Motor::Configs::SyncFromHash.call(
2830
YAML.safe_load(file.read, permitted_classes: [Time, Date])
2931
)

lib/motor/resources/fetch_configured_model.rb

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -114,36 +114,55 @@ def define_columns_hash(klass, config)
114114

115115
columns_hash =
116116
columns.each_with_object({}) do |column, acc|
117-
acc[column[:name]] =
118-
if Rails.version.to_f >= 7.2
119-
base_column.class.new(
120-
column[:name],
121-
nil,
122-
base_column.sql_type_metadata.class.new(
123-
ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: column[:column_type],
124-
type: column[:column_type].to_sym))
125-
)
126-
else
127-
ActiveRecord::ConnectionAdapters::Column.new(
128-
column[:name],
129-
nil,
130-
ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: column[:column_type],
131-
type: column[:column_type].to_sym)
132-
)
133-
end
117+
acc[column[:name]] = synthesize_column(base_column, column[:name], column[:column_type])
134118
end
135119

136120
klass.instance_variable_set(:@__motor_custom_sql_columns_hash, columns_hash)
137121

138122
# rubocop:disable Naming/MemoizedInstanceVariableName
139123
klass.instance_eval do
124+
# Expose custom_sql columns for reading/type-casting, but keep persistence
125+
# behavior based only on real DB columns.
140126
def columns_hash
141127
@__motor__columns_hash ||= @__motor_custom_sql_columns_hash.merge(super)
142128
end
129+
130+
# Only real DB columns should be considered for persistence and strong params.
131+
def column_names
132+
connection.schema_cache.columns_hash(table_name).keys
133+
end
134+
135+
# Same for the columns collection used by AR internals.
136+
def columns
137+
connection.schema_cache.columns(table_name)
138+
end
143139
end
144140
# rubocop:enable Naming/MemoizedInstanceVariableName
145141
end
146142

143+
def synthesize_column(template_column, name, sql_type)
144+
column = template_column.dup
145+
146+
generic_meta = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(
147+
sql_type: sql_type,
148+
type: sql_type.to_sym
149+
)
150+
151+
adapter_meta = template_column.sql_type_metadata.class.new(generic_meta)
152+
153+
begin
154+
cast_type = ActiveRecord::Type.lookup(sql_type.to_sym)
155+
rescue StandardError
156+
cast_type = ActiveRecord::Type.lookup(:string)
157+
end
158+
159+
column.instance_variable_set(:@name, name)
160+
column.instance_variable_set(:@sql_type_metadata, adapter_meta)
161+
column.instance_variable_set(:@cast_type, cast_type)
162+
163+
column
164+
end
165+
147166
def define_column_reflections(klass, config)
148167
config.fetch(:columns, []).each do |column|
149168
reference = column[:reference]

0 commit comments

Comments
 (0)