Don't access the database in after_initialize

Rails 5.2 crashes in the `db:create` task because it tries to run the
`after_initialize` block before the database is created.

The easiest way to solve it is to move the code out of the initializer
and calculate the API type definitions on demand. Note results are still
cached using a class instance variable (not to be confused with a class
variable), and so once definitions are obtained, they will remain
constant until the application is restarted, even in the development
environment.
This commit is contained in:
Javi Martín
2020-05-17 19:13:54 +02:00
parent 9837b1ab74
commit 6fd9a286d7
6 changed files with 15 additions and 21 deletions

View File

@@ -29,7 +29,7 @@ class GraphqlController < ApplicationController
private private
def consul_schema def consul_schema
api_types = GraphQL::ApiTypesCreator.create(API_TYPE_DEFINITIONS) api_types = GraphQL::ApiTypesCreator.create
query_type = GraphQL::QueryTypeCreator.create(api_types) query_type = GraphQL::QueryTypeCreator.create(api_types)
GraphQL::Schema.define do GraphQL::Schema.define do

View File

@@ -60,7 +60,6 @@ module Consul
config.after_initialize do config.after_initialize do
Globalize.set_fallbacks_to_all_available_locales Globalize.set_fallbacks_to_all_available_locales
GraphQLApi::Loader.setup
end end
config.assets.paths << Rails.root.join("app", "assets", "fonts") config.assets.paths << Rails.root.join("app", "assets", "fonts")

View File

@@ -1,11 +0,0 @@
module GraphQLApi
class Loader
def self.setup
if ActiveRecord::Base.connection.tables.any?
api_config = YAML.load_file("./config/api.yml")
GraphqlController.const_set "API_TYPE_DEFINITIONS",
GraphQL::ApiTypesCreator.parse_api_config_file(api_config)
end
end
end
end

View File

@@ -10,7 +10,7 @@ module GraphQL
string: GraphQL::STRING_TYPE string: GraphQL::STRING_TYPE
}.freeze }.freeze
def self.create(api_types_definitions) def self.create
created_types = {} created_types = {}
api_types_definitions.each do |model, info| api_types_definitions.each do |model, info|
create_type(model, info[:fields], created_types) create_type(model, info[:fields], created_types)
@@ -18,6 +18,10 @@ module GraphQL
created_types created_types
end end
def self.api_types_definitions
@api_types_definitions ||= parse_api_config_file(YAML.load_file(Rails.root.join("config/api.yml")))
end
def self.type_kind(type) def self.type_kind(type)
if SCALAR_TYPES[type] if SCALAR_TYPES[type]
:scalar :scalar

View File

@@ -1,13 +1,15 @@
require "rails_helper" require "rails_helper"
describe GraphQL::QueryTypeCreator do describe GraphQL::QueryTypeCreator do
let(:api_type_definitions) do before do
allow(GraphQL::ApiTypesCreator).to receive(:api_types_definitions).and_return(
{ {
ProposalNotification => { fields: { title: :string }}, ProposalNotification => { fields: { title: :string }},
Proposal => { fields: { id: :integer, title: :string }} Proposal => { fields: { id: :integer, title: :string }}
} }
)
end end
let(:api_types) { GraphQL::ApiTypesCreator.create(api_type_definitions) } let(:api_types) { GraphQL::ApiTypesCreator.create }
describe "::create" do describe "::create" do
let(:query_type) { GraphQL::QueryTypeCreator.create(api_types) } let(:query_type) { GraphQL::QueryTypeCreator.create(api_types) }

View File

@@ -1,6 +1,6 @@
require "rails_helper" require "rails_helper"
api_types = GraphQL::ApiTypesCreator.create(GraphqlController::API_TYPE_DEFINITIONS) api_types = GraphQL::ApiTypesCreator.create
query_type = GraphQL::QueryTypeCreator.create(api_types) query_type = GraphQL::QueryTypeCreator.create(api_types)
ConsulSchema = GraphQL::Schema.define do ConsulSchema = GraphQL::Schema.define do
query query_type query query_type