Fail to setup database_cleaner for dual database
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 35/100
Direzione di ricerca
Inizia in lib/database_cleaner/active_record/base.rb, soprattutto con connection_class, lookup_from_connection_pool ed establish_connection. Riproduci i due avvii di DatabaseCleaner con le connessioni test e secondary_test, quindi aggiungi una copertura di regressione che dimostri che Device e User mantengono le connessioni corrette senza che ActiveRecord::Base.establish_connection influisca su tutti i discendenti.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
I have two database, one with a model call Device, and the other has a model call User.
When I set up database_cleaner according to readme describe:
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner[:active_record,{:connection => :test}].strategy = :transaction
DatabaseCleaner[:active_record,{:connection => :secondary_test}].strategy = :transaction
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
I found that in my test, device model's connection will point to secondary_test database. And I will have following error as my secondary_test database don't have a table call devices:
ActiveRecord::StatementInvalid:
PG::UndefinedTable: ERROR: relation "devices" does not exist
LINE 5: WHERE a.attrelid = '"devices"'::regclass
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"devices"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
I dig in the code, and found that it is cause by #connection_class
def connection_class
@connection_class ||= if db && !db.is_a?(Symbol)
db
elsif connection_hash
lookup_from_connection_pool || establish_connection
else
::ActiveRecord::Base
end
end
private
def lookup_from_connection_pool
if ::ActiveRecord::Base.respond_to?(:descendants)
database_name = connection_hash["database"] || connection_hash[:database]
models = ::ActiveRecord::Base.descendants
models.detect { |m| m.connection_pool.spec.config[:database] == database_name }
end
end
def establish_connection
::ActiveRecord::Base.establish_connection(connection_hash)
end
However, since ::ActiveRecord::Base.descendants is blank when lookup_from_connection_pool is called, lookup_from_connection_pool would return nil, and establish_connection will be called. Unfortunately, ActiveRecord::Base.establish_connection(connection_hash) has a huge side effect in Rails 4+. It will set connection to specify one for ALL models that inherit from ActiveRecord::Base class. This can be reproduced by following code:
ActiveRecord::Base.establish_connection('test')
Device.connection
In my case, following code:
DatabaseCleaner[:active_record,{:connection => :test}].start
DatabaseCleaner[:active_record,{:connection => :secondary_test}].start
will first set ALL ActiveRecord::Base descendants' connections to test db, then it will set ALL their connection to secondary_test. Therefore, when I try to use Device in my spec, I will have PG::UndefinedTable: ERROR
Here is the similar issues that cause by the side effect for establish_connection:
- Lingua principale
- Ruby
- Stelle
- 3k
- Fork
- 485
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di DatabaseCleaner/database_cleaner
-
:transaction strategy: uncommitted data disappears after perform_enqueued_jobs on Rails ≥ 7.2Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 67/100
-
Cleaning of dev DBAperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 45/100
-
Cannot truncate a table referenced in a foreign key constraint (ActiveRecord::StatementInvalid)Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
DatabaseCleaner/database_cleaner#717 · 5 commenti · 1 reazione ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
DatabaseCleaner/database_cleaner#716 · 2 commenti ·
Tutte le issue di DatabaseCleaner/database_cleaner
Issue simili
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
jetrockets/jet_ui#47 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
FreeCAD/homebrew-freecad#870 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Messages with a markdown image that has a relative or malformed URL throw TypeError: Invalid URLAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno