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.
This commit is contained in:
parent
7d58fe941a
commit
70843ff7b2
@ -553,6 +553,20 @@ def reset_column_information
|
||||
initialize_find_by_cache
|
||||
end
|
||||
|
||||
def load_schema # :nodoc:
|
||||
return if schema_loaded?
|
||||
@load_schema_monitor.synchronize do
|
||||
return if @columns_hash
|
||||
|
||||
load_schema!
|
||||
|
||||
@schema_loaded = true
|
||||
rescue
|
||||
reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def initialize_load_schema_monitor
|
||||
@load_schema_monitor = Monitor.new
|
||||
@ -594,20 +608,6 @@ def schema_loaded?
|
||||
defined?(@schema_loaded) && @schema_loaded
|
||||
end
|
||||
|
||||
def load_schema
|
||||
return if schema_loaded?
|
||||
@load_schema_monitor.synchronize do
|
||||
return if @columns_hash
|
||||
|
||||
load_schema!
|
||||
|
||||
@schema_loaded = true
|
||||
rescue
|
||||
reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
def load_schema!
|
||||
unless table_name
|
||||
raise ActiveRecord::TableNotSpecified, "#{self} has no table configured. Set one with #{self}.table_name="
|
||||
|
@ -22,6 +22,12 @@
|
||||
exit 1
|
||||
end
|
||||
|
||||
if Rails.configuration.eager_load
|
||||
ActiveRecord::Base.descendants.each do |model|
|
||||
model.load_schema unless model.abstract_class?
|
||||
end
|
||||
end
|
||||
|
||||
ActiveSupport.on_load(:active_support_test_case) do
|
||||
include ActiveRecord::TestDatabases
|
||||
include ActiveRecord::TestFixtures
|
||||
|
@ -317,6 +317,39 @@ class UserTest < ActiveSupport::TestCase
|
||||
assert_not_includes output, "after:"
|
||||
end
|
||||
|
||||
test "schema for all the models is loaded when tests are run in eager load context" do
|
||||
output = rails("generate", "model", "user", "name:string")
|
||||
version = output.match(/(\d+)_create_users\.rb/)[1]
|
||||
|
||||
app_file "db/schema.rb", <<-RUBY
|
||||
ActiveRecord::Schema.define(version: #{version}) do
|
||||
create_table :users do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
||||
create_table :action_text_rich_texts
|
||||
create_table :active_storage_variant_records
|
||||
create_table :active_storage_blobs
|
||||
create_table :active_storage_attachments
|
||||
create_table :action_mailbox_inbound_emails do |t|
|
||||
t.integer :status
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
app_file "config/initializers/enable_eager_load.rb", <<-RUBY
|
||||
Rails.application.config.eager_load = true
|
||||
RUBY
|
||||
|
||||
app_file "app/models/user.rb", <<-RUBY
|
||||
class User < ApplicationRecord
|
||||
enum :type, [:admin, :user]
|
||||
end
|
||||
RUBY
|
||||
|
||||
assert_unsuccessful_run "models/user_test.rb", "Unknown enum attribute 'type' for User"
|
||||
end
|
||||
|
||||
private
|
||||
def assert_unsuccessful_run(name, message)
|
||||
result = run_test_file(name)
|
||||
|
Loading…
Reference in New Issue
Block a user