mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Eagerly define attribute methods in production
The attribute methods for a model are currently defined lazily the first time that model is instantiated, even when `config.eager_load` is true. This means the first request to use each model incurs the cost, which usually involves a database round trip to fetch the schema definition. By defining the attribute methods for all models while the application is booting, we move that work out of any individual request. When using a forking web server, this also reduces the number of times the schema definition is queried by doing it once in the parent process instead of from each forked process during their first request.
This commit is contained in:
parent
baffadaec9
commit
3b954786e7
2 changed files with 55 additions and 0 deletions
|
@ -137,6 +137,14 @@ end_error
|
|||
end
|
||||
end
|
||||
|
||||
initializer "active_record.define_attribute_methods" do |app|
|
||||
config.after_initialize do
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
descendants.each(&:define_attribute_methods) if app.config.eager_load
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
initializer "active_record.warn_on_records_fetched_greater_than" do
|
||||
if config.active_record.warn_on_records_fetched_greater_than
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
|
|
|
@ -310,6 +310,53 @@ module ApplicationTests
|
|||
assert_equal %w(noop_email).to_set, PostsMailer.instance_variable_get(:@action_methods)
|
||||
end
|
||||
|
||||
test "does not eager load attribute methods in development" do
|
||||
app_file "app/models/post.rb", <<-RUBY
|
||||
class Post < ActiveRecord::Base
|
||||
end
|
||||
RUBY
|
||||
|
||||
app_file "config/initializers/active_record.rb", <<-RUBY
|
||||
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
||||
ActiveRecord::Migration.verbose = false
|
||||
ActiveRecord::Schema.define(version: 1) do
|
||||
create_table :posts do |t|
|
||||
t.string :title
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
app "development"
|
||||
|
||||
assert_not_includes Post.instance_methods, :title
|
||||
end
|
||||
|
||||
test "eager loads attribute methods in production" do
|
||||
app_file "app/models/post.rb", <<-RUBY
|
||||
class Post < ActiveRecord::Base
|
||||
end
|
||||
RUBY
|
||||
|
||||
app_file "config/initializers/active_record.rb", <<-RUBY
|
||||
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
||||
ActiveRecord::Migration.verbose = false
|
||||
ActiveRecord::Schema.define(version: 1) do
|
||||
create_table :posts do |t|
|
||||
t.string :title
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
add_to_config <<-RUBY
|
||||
config.eager_load = true
|
||||
config.cache_classes = true
|
||||
RUBY
|
||||
|
||||
app "production"
|
||||
|
||||
assert_includes Post.instance_methods, :title
|
||||
end
|
||||
|
||||
test "initialize an eager loaded, cache classes app" do
|
||||
add_to_config <<-RUBY
|
||||
config.eager_load = true
|
||||
|
|
Loading…
Reference in a new issue