janko / rodauth-rails

Rails integration for Rodauth authentication framework
https://github.com/jeremyevans/rodauth
MIT License
599 stars 40 forks source link

Is it ready for a rails api only app? #13

Closed adilsoncarvalho closed 3 years ago

adilsoncarvalho commented 3 years ago

Howdy! ๐Ÿค 

First of all, thanks for putting this gem to make it easier to us all. Happy to collaborate to it. I am giving it a try on this gem to add Rodauth to my API only project, but I am facing some problems.

migrations don't run

The first one was regarding migrations. To run the migration I had to comment all the lines inside both ./config/initializers/rodauth.rb and ./config/initializers/sequel.rb. I was getting a connection error every time I tried to run migrations.

Another thing I noticed is that the generated ./config/initializers/sequel.rb looks like this:

require "sequel/core"

# initialize Sequel and have it reuse Active Record's database connection
DB = Sequel.postgres(extensions: :activerecord_connection)

And the version available at your example repo is slightly different:

require "sequel/core"

# initialize Sequel and have it reuse Active Record's database connection
DB = Sequel.postgres(extensions: :activerecord_connection)
DB.extension :activerecord_connection

RodauthApp could not be found

Later I had to deal with a NameError (uninitialized constant RodauthApp) error that I could solve moving the ./lib folder into ./app/lib.

alien method to an API only rails app being invoked

Now I am dealing with somewhere in the lib trying to use flash on an API only app: `NoMethodError (undefined method 'flash' for #

)` I am not sure if this is enough to let the gem know that we want the REST API only. ```ruby class RodauthApp < Rodauth::Rails::App configure :json => :only do # lots of stuff end ``` ### the relevant gems on my project ``` ruby '2.7.0' gem 'rails', '~> 6.0', '>= 6.0.2.2' gem 'pg', '>= 0.18', '< 2.0' gem 'rodauth-rails', '~> 0.3' ``` Any help is welcome. Thanks!
janko commented 3 years ago

Hi there ๐Ÿ‘‹

Happy to hear you're giving it a try, and thanks for sharing the obstacles you came across, I'll try to help as best I can ๐Ÿ˜ƒ

The first one was regarding migrations. To run the migration I had to comment all the lines inside both ./config/initializers/rodauth.rb and ./config/initializers/sequel.rb. I was getting a connection error every time I tried to run migrations.

What kind of connection error were you getting? What Sequel will do by default on initialization is try to connect to the database. Maybe that causes issues if Rails doesn't expect the connection to be established during app initialization. I don't know exactly why Rails would mind it, but if it does, I would like to understand the reasons.

Note that you can disable Sequel checking out a connection by passing test: false to the Sequel.postgres call.

Later I had to deal with a NameError (uninitialized constant RodauthApp) error that I could solve moving the ./lib folder into ./app/lib.

Did you remember to add the lib/ directory to config.autoload_paths? But app/lib/ works too ๐Ÿ‘ Maybe I'll even change rodauth-rails to create rodauth_app.rb in app/lib/, because by nature it is "app" code. And that way people don't have to remember to update config.autoload_paths.

Now I am dealing with somewhere in the lib trying to use flash on an API only app: NoMethodError (undefined method 'flash' for # )

Oh, it seems rodauth-rails will always try to call the #flash method, even if you set json: :only. Ideally it should handle Rails API mode automatically. I will work on fixing that.

janko commented 3 years ago

I've just pushed some changes to master for API-only mode:

I've tested the new changes now on a vanilla Rails application in API-only mode, and everything seems to be working.

janko commented 3 years ago

Just released version 0.4.0 with these changes. Rails API-mode should be working now, but let me know if you have additional problems with it.

Btw, this is the correct Sequel initializer (I've updated rodauth-demo-rails with this now as well):

require "sequel/core"

# initialize Sequel and have it reuse Active Record's database connection
DB = Sequel.postgres(extensions: :activerecord_connection)
adilsoncarvalho commented 3 years ago

Thank you for providing a fix so quickly.

๐ŸŽ‰ The invocation of flash method is fixed!

Unfortunately, the database problem still happening. I discovered that it only happens when I try to create the database. I created a repo with the vanilla rails API app I used and my docker setup. I hope it helps.

The steps:

I have the following questions:

Here is the trace for the failed rake db:create. It feels like some other component tries to reach the database before its creation, and then fails because it doesn't exist.

rake aborted!
ActiveRecord::NoDatabaseError: FATAL:  database "api_development" does not exist
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/postgresql_adapter.rb:50:in `rescue in postgresql_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/postgresql_adapter.rb:33:in `postgresql_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:887:in `new_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:931:in `checkout_new_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:910:in `try_to_checkout_new_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:871:in `acquire_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:593:in `checkout'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:437:in `connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:1119:in `retrieve_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_handling.rb:221:in `retrieve_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_handling.rb:189:in `connection'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection.rb:130:in `activerecord_connection'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection.rb:122:in `activerecord_lock'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection.rb:34:in `synchronize'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection/postgres.rb:5:in `synchronize'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/connecting.rb:278:in `test_connection'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/misc.rb:169:in `initialize'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/connecting.rb:57:in `new'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/connecting.rb:57:in `connect'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/core.rb:124:in `connect'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/core.rb:402:in `adapter_method'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/core.rb:409:in `block (2 levels) in def_adapter_method'
/api/config/initializers/sequel.rb:4:in `<main>'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:318:in `block in load'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:318:in `load'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:666:in `block in load_config_initializer'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/notifications.rb:182:in `instrument'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:665:in `load_config_initializer'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:625:in `block (2 levels) in <class:Engine>'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:624:in `each'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:624:in `block in <class:Engine>'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:32:in `instance_exec'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:32:in `run'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:61:in `block in run_initializers'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:50:in `each'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:50:in `tsort_each_child'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:60:in `run_initializers'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/application.rb:363:in `initialize!'
/api/config/environment.rb:5:in `<main>'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
/usr/local/bundle/gems/zeitwerk-2.4.1/lib/zeitwerk/kernel.rb:33:in `require'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `block in require'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `require'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/application.rb:339:in `require_environment!'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/application.rb:523:in `block in run_tasks_blocks'

Caused by:
PG::ConnectionBad: FATAL:  database "api_development" does not exist
/usr/local/bundle/gems/pg-1.2.3/lib/pg.rb:58:in `initialize'
/usr/local/bundle/gems/pg-1.2.3/lib/pg.rb:58:in `new'
/usr/local/bundle/gems/pg-1.2.3/lib/pg.rb:58:in `connect'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/postgresql_adapter.rb:46:in `postgresql_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:887:in `new_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:931:in `checkout_new_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:910:in `try_to_checkout_new_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:871:in `acquire_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:593:in `checkout'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:437:in `connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:1119:in `retrieve_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_handling.rb:221:in `retrieve_connection'
/usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_handling.rb:189:in `connection'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection.rb:130:in `activerecord_connection'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection.rb:122:in `activerecord_lock'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection.rb:34:in `synchronize'
/usr/local/bundle/gems/sequel-activerecord_connection-1.0.1/lib/sequel/extensions/activerecord_connection/postgres.rb:5:in `synchronize'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/connecting.rb:278:in `test_connection'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/misc.rb:169:in `initialize'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/connecting.rb:57:in `new'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/database/connecting.rb:57:in `connect'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/core.rb:124:in `connect'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/core.rb:402:in `adapter_method'
/usr/local/bundle/gems/sequel-5.38.0/lib/sequel/core.rb:409:in `block (2 levels) in def_adapter_method'
/api/config/initializers/sequel.rb:4:in `<main>'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:318:in `block in load'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:318:in `load'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:666:in `block in load_config_initializer'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/notifications.rb:182:in `instrument'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:665:in `load_config_initializer'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:625:in `block (2 levels) in <class:Engine>'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:624:in `each'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/engine.rb:624:in `block in <class:Engine>'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:32:in `instance_exec'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:32:in `run'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:61:in `block in run_initializers'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:50:in `each'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:50:in `tsort_each_child'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/initializable.rb:60:in `run_initializers'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/application.rb:363:in `initialize!'
/api/config/environment.rb:5:in `<main>'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
/usr/local/bundle/gems/bootsnap-1.5.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
/usr/local/bundle/gems/zeitwerk-2.4.1/lib/zeitwerk/kernel.rb:33:in `require'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `block in require'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency'
/usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `require'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/application.rb:339:in `require_environment!'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/application.rb:523:in `block in run_tasks_blocks'
Tasks: TOP => db:create => db:load_config => environment
(See full trace by running task with --trace)