Skip to content

Commit 70843ff

Browse files
committed
Load the model schema when running test in eager load context
Some protections like the one that checks if an enum is pointing to a valid column in the table only works when the database schema is loaded to the model. Before this change, if schema cache wasn't present and the right combinations of configurations were not set, developers would only see this exception in production. With this change, those errors would be caught on CI, as soon the tests are loaded.
1 parent 7d58fe9 commit 70843ff

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

activerecord/lib/active_record/model_schema.rb

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,20 @@ def reset_column_information
553553
initialize_find_by_cache
554554
end
555555

556+
def load_schema # :nodoc:
557+
return if schema_loaded?
558+
@load_schema_monitor.synchronize do
559+
return if @columns_hash
560+
561+
load_schema!
562+
563+
@schema_loaded = true
564+
rescue
565+
reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
566+
raise
567+
end
568+
end
569+
556570
protected
557571
def initialize_load_schema_monitor
558572
@load_schema_monitor = Monitor.new
@@ -594,20 +608,6 @@ def schema_loaded?
594608
defined?(@schema_loaded) && @schema_loaded
595609
end
596610

597-
def load_schema
598-
return if schema_loaded?
599-
@load_schema_monitor.synchronize do
600-
return if @columns_hash
601-
602-
load_schema!
603-
604-
@schema_loaded = true
605-
rescue
606-
reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
607-
raise
608-
end
609-
end
610-
611611
def load_schema!
612612
unless table_name
613613
raise ActiveRecord::TableNotSpecified, "#{self} has no table configured. Set one with #{self}.table_name="

railties/lib/rails/test_help.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
exit 1
2323
end
2424

25+
if Rails.configuration.eager_load
26+
ActiveRecord::Base.descendants.each do |model|
27+
model.load_schema unless model.abstract_class?
28+
end
29+
end
30+
2531
ActiveSupport.on_load(:active_support_test_case) do
2632
include ActiveRecord::TestDatabases
2733
include ActiveRecord::TestFixtures

railties/test/application/test_test.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,39 @@ class UserTest < ActiveSupport::TestCase
317317
assert_not_includes output, "after:"
318318
end
319319

320+
test "schema for all the models is loaded when tests are run in eager load context" do
321+
output = rails("generate", "model", "user", "name:string")
322+
version = output.match(/(\d+)_create_users\.rb/)[1]
323+
324+
app_file "db/schema.rb", <<-RUBY
325+
ActiveRecord::Schema.define(version: #{version}) do
326+
create_table :users do |t|
327+
t.string :name
328+
end
329+
330+
create_table :action_text_rich_texts
331+
create_table :active_storage_variant_records
332+
create_table :active_storage_blobs
333+
create_table :active_storage_attachments
334+
create_table :action_mailbox_inbound_emails do |t|
335+
t.integer :status
336+
end
337+
end
338+
RUBY
339+
340+
app_file "config/initializers/enable_eager_load.rb", <<-RUBY
341+
Rails.application.config.eager_load = true
342+
RUBY
343+
344+
app_file "app/models/user.rb", <<-RUBY
345+
class User < ApplicationRecord
346+
enum :type, [:admin, :user]
347+
end
348+
RUBY
349+
350+
assert_unsuccessful_run "models/user_test.rb", "Unknown enum attribute 'type' for User"
351+
end
352+
320353
private
321354
def assert_unsuccessful_run(name, message)
322355
result = run_test_file(name)

0 commit comments

Comments
 (0)