问:
Can't deploy Rails 6 app to Heroku. ErrorLog included
I've build a Rails 6 app using React via the newly integrated Webpacker for JS and can't seem to get over the final hurdle of deploying to Heroku. I don't quite understand the logs. I did create a Procfile to launch Puma and Webpack server. Would anyone mind looking at the logs and tell me what I might be missing? BTW, the first hurdle was getting rid of a Yarn vs NPM lockfile conflict.

Here are the logs:

```<code>2020-02-15T19:10:42.074186+00:00 app[web.1]: bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.6.0/bin/puma)
2020-02-15T19:10:42.074256+00:00 app[web.1]: ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "outages" does not exist
2020-02-15T19:10:42.074256+00:00 app[web.1]: LINE 8:  WHERE a.attrelid = '"outages"'::regclass
2020-02-15T19:10:42.074257+00:00 app[web.1]: ^
2020-02-15T19:10:42.074269+00:00 app[web.1]:
2020-02-15T19:10:42.074271+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:65:in `exec'
2020-02-15T19:10:42.074274+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:65:in `block (2 levels) in query'
2020-02-15T19:10:42.074274+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
2020-02-15T19:10:42.074275+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
2020-02-15T19:10:42.074275+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
2020-02-15T19:10:42.074275+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:64:in `block in query'
2020-02-15T19:10:42.074276+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:718:in `block (2 levels) in log'
2020-02-15T19:10:42.074276+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
2020-02-15T19:10:42.074276+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:717:in `block in log'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:708:in `log'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:63:in `query'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:817:in `column_definitions'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:114:in `columns'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/schema_cache.rb:76:in `columns'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/schema_cache.rb:82:in `columns_hash'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:490:in `load_schema!'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/attributes.rb:247:in `load_schema!'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/attribute_decorators.rb:51:in `load_schema!'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:480:in `block in load_schema'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:477:in `load_schema'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:352:in `columns_hash'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1216:in `arel_column'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1203:in `block in arel_columns'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1196:in `each'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1196:in `flat_map'
2020-02-15T19:10:42.074281+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1196:in `arel_columns'
2020-02-15T19:10:42.074281+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1187:in `build_select'
2020-02-15T19:10:42.074281+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1071:in `build_arel'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1016:in `arel'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/finder_methods.rb:317:in `block in exists?'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation.rb:828:in `skip_query_cache_if_necessary'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/finder_methods.rb:317:in `exists?'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/querying.rb:21:in `exists?'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/app/controllers/application_controller.rb:3:in `<class:ApplicationController>'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/app/controllers/application_controller.rb:1:in `<main>'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:16:in `require'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/app/controllers/dashboard_controller.rb:1:in `<main>'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:16:in `require'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:351:in `const_get'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:351:in `block (2 levels) in eager_load'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:685:in `block in ls'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:682:in `foreach'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:682:in `ls'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:346:in `block in eager_load'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:338:in `synchronize'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:338:in `eager_load'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:449:in `each'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:449:in `eager_load_all'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/application/finisher.rb:122:in `block in <module:Finisher>'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `instance_exec'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `run'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:61:in `block in run_initializers'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'
2020-02-15T19:10:42.074294+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'
2020-02-15T19:10:42.074294+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `each'
2020-02-15T19:10:42.074294+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `call'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:60:in `run_initializers'
2020-02-15T19:10:42.074296+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/application.rb:363:in `initialize!'
2020-02-15T19:10:42.074296+00:00 app[web.1]: /app/config/environment.rb:5:in `<top (required)>'
2020-02-15T19:10:42.074297+00:00 app[web.1]: config.ru:3:in `require_relative'
2020-02-15T19:10:42.074297+00:00 app[web.1]: config.ru:3:in `block in <main>'
2020-02-15T19:10:42.074315+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:116:in `eval'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:116:in `new_from_string'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:105:in `load_file'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:66:in `parse_file'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/configuration.rb:321:in `load_rackup'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/configuration.rb:246:in `app'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/runner.rb:155:in `load_and_bind'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/single.rb:98:in `run'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/launcher.rb:172:in `run'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/cli.rb:80:in `run'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/bin/puma:10:in `<top (required)>'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/bin/puma:23:in `load'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/bin/puma:23:in `<top (required)>'
2020-02-15T19:10:42.174683+00:00 heroku[web.1]: State changed from starting to crashed
2020-02-15T19:10:42.158245+00:00 heroku[web.1]: Process exited with status 1
2020-02-15T19:10:43.902737+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=tml-dashboard.herokuapp.com request_id=c6f9e222-b62f-47e2-b5eb-5befc8af9ad2 fwd="68.194.85.143" dyno= connect= service= status=503 bytes= protocol=https
2020-02-15T19:10:45.661172+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=tml-dashboard.herokuapp.com request_id=25660d39-0184-411c-8e94-d54fcbd0d7b3 fwd="68.194.85.143" dyno= connect= service= status=503 bytes= protocol=https

</code>```

答:
Looks like you weren't run rails db:migrate after you deployed your app. Unfortunately / fortunately Heroku doesn't run migrations after deploy.

As fast fix: you can run heroku bash(you can do it in a few ways):

$heroku run bash --app your_application_name

Through GUI of Heroku

and just run it manually: rails db:migrate

To avoid it in future you can add to your Procfile release phase
where you can just set what you want to do after deploy

# Procfile
release: rake db:migrate
```

Body:
I've build a Rails 6 app using React via the newly integrated Webpacker for JS and can't seem to get over the final hurdle of deploying to Heroku. I don't quite understand the logs. I did create a Procfile to launch Puma and Webpack server. Would anyone mind looking at the logs and tell me what I might be missing? BTW, the first hurdle was getting rid of a Yarn vs NPM lockfile conflict.

Here are the logs:

2020-02-15T19:10:42.074186+00:00 app[web.1]: bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.6.0/bin/puma)
2020-02-15T19:10:42.074256+00:00 app[web.1]: ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "outages" does not exist
2020-02-15T19:10:42.074256+00:00 app[web.1]: LINE 8:  WHERE a.attrelid = '"outages"'::regclass
2020-02-15T19:10:42.074257+00:00 app[web.1]: ^
2020-02-15T19:10:42.074269+00:00 app[web.1]:
2020-02-15T19:10:42.074271+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:65:in `exec'
2020-02-15T19:10:42.074274+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:65:in `block (2 levels) in query'
2020-02-15T19:10:42.074274+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
2020-02-15T19:10:42.074275+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
2020-02-15T19:10:42.074275+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
2020-02-15T19:10:42.074275+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:64:in `block in query'
2020-02-15T19:10:42.074276+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:718:in `block (2 levels) in log'
2020-02-15T19:10:42.074276+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
2020-02-15T19:10:42.074276+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:717:in `block in log'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:708:in `log'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:63:in `query'
2020-02-15T19:10:42.074277+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:817:in `column_definitions'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:114:in `columns'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/schema_cache.rb:76:in `columns'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/schema_cache.rb:82:in `columns_hash'
2020-02-15T19:10:42.074278+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:490:in `load_schema!'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/attributes.rb:247:in `load_schema!'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/attribute_decorators.rb:51:in `load_schema!'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:480:in `block in load_schema'
2020-02-15T19:10:42.074279+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:477:in `load_schema'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/model_schema.rb:352:in `columns_hash'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1216:in `arel_column'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1203:in `block in arel_columns'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1196:in `each'
2020-02-15T19:10:42.074280+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1196:in `flat_map'
2020-02-15T19:10:42.074281+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1196:in `arel_columns'
2020-02-15T19:10:42.074281+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1187:in `build_select'
2020-02-15T19:10:42.074281+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1071:in `build_arel'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/query_methods.rb:1016:in `arel'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/finder_methods.rb:317:in `block in exists?'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation.rb:828:in `skip_query_cache_if_necessary'
2020-02-15T19:10:42.074284+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/relation/finder_methods.rb:317:in `exists?'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/querying.rb:21:in `exists?'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/app/controllers/application_controller.rb:3:in `<class:ApplicationController>'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/app/controllers/application_controller.rb:1:in `'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
2020-02-15T19:10:42.074285+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
2020-02-15T19:10:42.074286+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:16:in `require'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/app/controllers/dashboard_controller.rb:1:in `'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
2020-02-15T19:10:42.074287+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:16:in `require'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:351:in `const_get'
2020-02-15T19:10:42.074288+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:351:in `block (2 levels) in eager_load'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:685:in `block in ls'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:682:in `foreach'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:682:in `ls'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:346:in `block in eager_load'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:338:in `synchronize'
2020-02-15T19:10:42.074289+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:338:in `eager_load'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:449:in `each'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:449:in `eager_load_all'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/application/finisher.rb:122:in `block in <module:Finisher>'
2020-02-15T19:10:42.074290+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `instance_exec'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `run'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:61:in `block in run_initializers'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
2020-02-15T19:10:42.074291+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'
2020-02-15T19:10:42.074294+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'
2020-02-15T19:10:42.074294+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `each'
2020-02-15T19:10:42.074294+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `call'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/ruby-2.6.3/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'
2020-02-15T19:10:42.074295+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:60:in `run_initializers'
2020-02-15T19:10:42.074296+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/application.rb:363:in `initialize!'
2020-02-15T19:10:42.074296+00:00 app[web.1]: /app/config/environment.rb:5:in `<top (required)>'
2020-02-15T19:10:42.074297+00:00 app[web.1]: config.ru:3:in `require_relative'
2020-02-15T19:10:42.074297+00:00 app[web.1]: config.ru:3:in `block in '
2020-02-15T19:10:42.074315+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:116:in `eval'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:116:in `new_from_string'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:105:in `load_file'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.2/lib/rack/builder.rb:66:in `parse_file'
2020-02-15T19:10:42.074316+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/configuration.rb:321:in `load_rackup'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/configuration.rb:246:in `app'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/runner.rb:155:in `load_and_bind'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/single.rb:98:in `run'
2020-02-15T19:10:42.074317+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/launcher.rb:172:in `run'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/lib/puma/cli.rb:80:in `run'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.1/bin/puma:10:in `<top (required)>'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/bin/puma:23:in `load'
2020-02-15T19:10:42.074318+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/bin/puma:23:in `<top (required)>'
2020-02-15T19:10:42.174683+00:00 heroku[web.1]: State changed from starting to crashed
2020-02-15T19:10:42.158245+00:00 heroku[web.1]: Process exited with status 1
2020-02-15T19:10:43.902737+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=tml-dashboard.herokuapp.com request_id=c6f9e222-b62f-47e2-b5eb-5befc8af9ad2 fwd="68.194.85.143" dyno= connect= service= status=503 bytes= protocol=https
2020-02-15T19:10:45.661172+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=tml-dashboard.herokuapp.com request_id=25660d39-0184-411c-8e94-d54fcbd0d7b3 fwd="68.194.85.143" dyno= connect= service= status=503 bytes= protocol=https


来源: stackexchange

问:
Randomly redirect with PHP
I'm trying to redirect 2 URL randomly but it not working.

My Code

<?php
$urls=readStack();
if(empty($urls)) {
    $urls = shuffle(array('https://domain1.com', 'https://domain2.com'));
    $url=array_pop($urls);
    storeStack($urls);
    header('Location:' .$url);
?>
```

Help how to fix this?

答:
I don't know what readStack() and storeStack() are but you probably want something like

```<code>$arr = array('https://domain1.com', 'https://domain2.com');
shuffle($arr); // This returns a boolean and the array is modified inside the function so just pass in the array
$url=array_pop($arr); // Pop the top most element from the array and store into $url
header("Location: $url");
</code>```

That code alone gives you a random url from those two

ContentLicense: CC BY-SA 4.0

Title: Randomly redirect with PHP

Body:
I'm trying to redirect 2 URL randomly but it not working.

My Code

<?php
$urls=readStack();
if(empty($urls)) {
    $urls = shuffle(array('https://domain1.com', 'https://domain2.com'));
    $url=array_pop($urls);
    storeStack($urls);
    header('Location:' .$url);
?>

Help how to fix this?

Body:
I don't know what readStack() and storeStack() are but you probably want something like

$arr = array('https://domain1.com', 'https://domain2.com');
shuffle($arr); // This returns a boolean and the array is modified inside the function so just pass in the array
$url=array_pop($arr); // Pop the top most element from the array and store into $url
header("Location: $url");

That code alone gives you a random url from those two


问:
Components alignment in android studio's layout preview does not match with what the device shows
Preview of Android Studio's Layout

Preview of Device's Layout

As you can see in the pictures above, the alignment of the components is properly arranged but when it is run it appears that the bottom components (TextView and a Switch) are cut. Is there something I must do so that my components' alignment in the android studio's layout shows exactly what I will see when I use the application on my device?

My device is Samsung SM-G610Y. Resolution: 1080 by 1920; Diagonal: 5.5 inches; Android 6.1 (Marshmallow).
These are also the specifications I "plugged-in" when creating the Android Virtual Device.

This is the XML file of the layout.

```<code><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/constraintLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="visible">

            <Button
                android:id="@+id/editAlarm1"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="120dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime1"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/editAlarm2"
                app:layout_constraintEnd_toStartOf="@+id/alarmText1"
                tools:visibility="visible" />

            <Button
                android:id="@+id/editAlarm2"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="120dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime2"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/editAlarm3"
                app:layout_constraintEnd_toStartOf="@+id/alarmText2"
                tools:visibility="visible" />

            <Button
                android:id="@+id/editAlarm3"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="120dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime3"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/editAlarm4"
                app:layout_constraintEnd_toStartOf="@+id/alarmText3"
                tools:visibility="visible" />

            <Button
                android:id="@+id/editAlarm4"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="65dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime4"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/alarmText4"
                tools:visibility="visible" />

            <Switch
                android:id="@+id/alarmSwitch1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:height="40sp"
                android:gravity="center_horizontal|center_vertical"
                android:hapticFeedbackEnabled="false"
                android:scrollbarSize="4dp"
                android:textSize="14sp"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText1"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText1"
                app:layout_constraintTop_toTopOf="@+id/alarmText1"
                tools:visibility="visible" />

            <Switch
                android:id="@+id/alarmSwitch2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText2"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText2"
                app:layout_constraintTop_toTopOf="@+id/alarmText2" />

            <Switch
                android:id="@+id/alarmSwitch3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:height="40sp"
                android:gravity="center_horizontal|center_vertical"
                android:hapticFeedbackEnabled="false"
                android:scrollbarSize="4dp"
                android:textSize="14sp"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText3"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText3"
                app:layout_constraintTop_toTopOf="@+id/alarmText3" />

            <Switch
                android:id="@+id/alarmSwitch4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:height="40sp"
                android:gravity="center_horizontal|center_vertical"
                android:hapticFeedbackEnabled="false"
                android:scrollbarSize="4dp"
                android:textSize="14sp"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText4"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText4"
                app:layout_constraintTop_toTopOf="@+id/alarmText4" />

            <TextView
                android:id="@+id/alarmText1"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginTop="125dp"
                android:layout_marginBottom="90dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toTopOf="@+id/alarmText2"
                app:layout_constraintStart_toEndOf="@+id/alarmText4"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/alarmText2"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginBottom="90dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toTopOf="@+id/alarmText3"
                app:layout_constraintStart_toStartOf="parent" />

            <TextView
                android:id="@+id/alarmText3"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginBottom="90dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toTopOf="@+id/alarmText4"
                app:layout_constraintStart_toEndOf="@+id/alarmText2"
                app:layout_constraintStart_toStartOf="parent" />

            <TextView
                android:id="@+id/alarmText4"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginBottom="50dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toEndOf="@+id/alarmText3"
                app:layout_constraintStart_toStartOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>

    <Button
        android:id="@+id/editButton"
        android:layout_width="56dp"
        android:layout_height="35dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginRight="10dp"
        android:text="EDIT"
        android:textAllCaps="false"
        android:textSize="12sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnGo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to Quiz Activity"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
</code>```

答:
You are using too many fixed sizes on your view:

Different phones got different screen sizes, in your layout, you are using fixed size on your views (fixed size android:layout_width="56dp" for example) and the result is that what may look good on one screen (your preview screen) will not look good on another screen (your actual phone).

If you want to make your layout responsive you can use:

```<code>  app:layout_constraintHeight_percent="0.y"
  app:layout_constraintWidth_percent="0.x"
</code>```

Together with Guidelines to make your layout responsive, for example you can use this for your rows:

```<code>    <androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout_editor_absoluteX="40dp"
    tools:layout_editor_absoluteY="-16dp">

    <Button
        android:id="@+id/button4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Button1"
        app:layout_constraintBottom_toBottomOf="@+id/button3"
        app:layout_constraintEnd_toStartOf="@+id/button3"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/button2"
        app:layout_constraintTop_toTopOf="@+id/button3"
        app:layout_constraintWidth_percent="0.3" />

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Button2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/button4"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.3" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="1"
        app:layout_constraintBottom_toBottomOf="@+id/button3"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toStartOf="@+id/button4"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/button3" />

</androidx.constraintlayout.widget.ConstraintLayout>
</code>```

And from here just Implement this on your layout in any way that you want to.

Body:
Preview of Android Studio's Layout

Preview of Device's Layout

As you can see in the pictures above, the alignment of the components is properly arranged but when it is run it appears that the bottom components (TextView and a Switch) are cut. Is there something I must do so that my components' alignment in the android studio's layout shows exactly what I will see when I use the application on my device?

My device is Samsung SM-G610Y. Resolution: 1080 by 1920; Diagonal: 5.5 inches; Android 6.1 (Marshmallow).
These are also the specifications I "plugged-in" when creating the Android Virtual Device.

This is the XML file of the layout.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/constraintLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="visible">

            <Button
                android:id="@+id/editAlarm1"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="120dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime1"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/editAlarm2"
                app:layout_constraintEnd_toStartOf="@+id/alarmText1"
                tools:visibility="visible" />

            <Button
                android:id="@+id/editAlarm2"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="120dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime2"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/editAlarm3"
                app:layout_constraintEnd_toStartOf="@+id/alarmText2"
                tools:visibility="visible" />

            <Button
                android:id="@+id/editAlarm3"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="120dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime3"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/editAlarm4"
                app:layout_constraintEnd_toStartOf="@+id/alarmText3"
                tools:visibility="visible" />

            <Button
                android:id="@+id/editAlarm4"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginBottom="65dp"
                android:background="@android:drawable/ic_menu_edit"
                android:onClick="setTime4"
                android:textSize="0sp"
                android:visibility="invisible"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/alarmText4"
                tools:visibility="visible" />

            <Switch
                android:id="@+id/alarmSwitch1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:height="40sp"
                android:gravity="center_horizontal|center_vertical"
                android:hapticFeedbackEnabled="false"
                android:scrollbarSize="4dp"
                android:textSize="14sp"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText1"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText1"
                app:layout_constraintTop_toTopOf="@+id/alarmText1"
                tools:visibility="visible" />

            <Switch
                android:id="@+id/alarmSwitch2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText2"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText2"
                app:layout_constraintTop_toTopOf="@+id/alarmText2" />

            <Switch
                android:id="@+id/alarmSwitch3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:height="40sp"
                android:gravity="center_horizontal|center_vertical"
                android:hapticFeedbackEnabled="false"
                android:scrollbarSize="4dp"
                android:textSize="14sp"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText3"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText3"
                app:layout_constraintTop_toTopOf="@+id/alarmText3" />

            <Switch
                android:id="@+id/alarmSwitch4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:height="40sp"
                android:gravity="center_horizontal|center_vertical"
                android:hapticFeedbackEnabled="false"
                android:scrollbarSize="4dp"
                android:textSize="14sp"
                app:layout_constraintBottom_toBottomOf="@+id/alarmText4"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.75"
                app:layout_constraintStart_toEndOf="@+id/alarmText4"
                app:layout_constraintTop_toTopOf="@+id/alarmText4" />

            <TextView
                android:id="@+id/alarmText1"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginTop="125dp"
                android:layout_marginBottom="90dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toTopOf="@+id/alarmText2"
                app:layout_constraintStart_toEndOf="@+id/alarmText4"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/alarmText2"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginBottom="90dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toTopOf="@+id/alarmText3"
                app:layout_constraintStart_toStartOf="parent" />

            <TextView
                android:id="@+id/alarmText3"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginBottom="90dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toTopOf="@+id/alarmText4"
                app:layout_constraintStart_toEndOf="@+id/alarmText2"
                app:layout_constraintStart_toStartOf="parent" />

            <TextView
                android:id="@+id/alarmText4"
                android:layout_width="159dp"
                android:layout_height="49dp"
                android:layout_marginStart="48dp"
                android:layout_marginLeft="48dp"
                android:layout_marginBottom="50dp"
                android:text="@string/default_alarm_time"
                android:textSize="35sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toEndOf="@+id/alarmText3"
                app:layout_constraintStart_toStartOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>

    <Button
        android:id="@+id/editButton"
        android:layout_width="56dp"
        android:layout_height="35dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginRight="10dp"
        android:text="EDIT"
        android:textAllCaps="false"
        android:textSize="12sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnGo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to Quiz Activity"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Body:
You are using too many fixed sizes on your view:

Different phones got different screen sizes, in your layout, you are using fixed size on your views (fixed size android:layout_width="56dp" for example) and the result is that what may look good on one screen (your preview screen) will not look good on another screen (your actual phone).

If you want to make your layout responsive you can use:

  app:layout_constraintHeight_percent="0.y"
  app:layout_constraintWidth_percent="0.x"

Together with Guidelines to make your layout responsive, for example you can use this for your rows:

    <androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout_editor_absoluteX="40dp"
    tools:layout_editor_absoluteY="-16dp">

    <Button
        android:id="@+id/button4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Button1"
        app:layout_constraintBottom_toBottomOf="@+id/button3"
        app:layout_constraintEnd_toStartOf="@+id/button3"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/button2"
        app:layout_constraintTop_toTopOf="@+id/button3"
        app:layout_constraintWidth_percent="0.3" />

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Button2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/button4"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.3" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="1"
        app:layout_constraintBottom_toBottomOf="@+id/button3"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toStartOf="@+id/button4"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/button3" />

</androidx.constraintlayout.widget.ConstraintLayout>

And from here just Implement this on your layout in any way that you want to.


问:
Vue.js random color appended to user list everytime page is (re)loaded
I have some jQuery code I want to convert to Vue.js. Basically, everytime I (re)load the page, a random color is given to each user of a list and its different everytime.

Here is the jQuery code:

```<code>//RANDOM USER COLOR
    $(".usersElements").each(function(index) {
    var idUser = $(this).attr("id");
        if ($.inArray(idUser, usersColors) == -1) {
            var letters = '0123456789ABCDEF';
            var color = '#';
            for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        usersColors.push(idUser);
        colors.push(color);
        $(this).find(".colorsByUser").css("background-color", color);
        } else {
            var index = usersColors.indexOf(idUser);
            $(this).find(".colorsByUser").css("background-color", colors[index]);
        }
    });
</code>```

I forgot to mention and this might be important. The list of users is dynamic and called with PHP.
Here is the HTML:

```<code>                <div class="col-md-12">
                   <div id="users" name="users">
                   <!--- section to display the list of users starts -->
                        <?php   if(!empty($user))
                        {
                            foreach($user as $value)
                            {
                            ?>
                                <div class="row oddEven usersElements userid" id=<?php echo $value->id;?> style="margin-top: -1vw;">
                                    <div v-on:click="displayAgregators(<?php echo $value->id;?>)" class="col-md-10">
                                        <span id="items<?php echo $value->id;?>"><?php echo ucfirst($value->username);?></span>
                                    </div>
                                    <div class="col-md-2">
                                        <div class="colorsByUser"></div>
                                    </div>
                                </div>
                            <?php }
                        }?>
                    </div>
                </div>
</code>```

I have searched for different solutions, but nothing directly related to the problem.
Hope you guys can help!

答:
You can have some pre-defined colours,  and then randomly chose which colour to show</p>

```<code><div :class="randomColors"></div>
</code>```

```<code>data(){
return {
      colors: [
        "red",
        "blue",
        "green",
        "indigo",
        "purple",
        "teal",
        "orange",
        "brown",
        "deep-orange",
        "blue-grey",
        "cyan"
      ],
      currentColor: ""
    }
},

 methods: {
    randomColors() {
      this.currentColor =
        this.colors[Math.floor(Math.random() * this.colors.length)];
    },
  }
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I have some jQuery code I want to convert to Vue.js. Basically, everytime I (re)load the page, a random color is given to each user of a list and its different everytime.

Here is the jQuery code:

//RANDOM USER COLOR
    $(".usersElements").each(function(index) {
    var idUser = $(this).attr("id");
        if ($.inArray(idUser, usersColors) == -1) {
            var letters = '0123456789ABCDEF';
            var color = '#';
            for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        usersColors.push(idUser);
        colors.push(color);
        $(this).find(".colorsByUser").css("background-color", color);
        } else {
            var index = usersColors.indexOf(idUser);
            $(this).find(".colorsByUser").css("background-color", colors[index]);
        }
    });

I forgot to mention and this might be important. The list of users is dynamic and called with PHP.
Here is the HTML:

                        <?php   if(!empty($user))
                        {
                            foreach($user as $value)
                            {
                            ?>
                                <div class="row oddEven usersElements userid" id=<?php echo $value->id;?> style="margin-top: -1vw;">
                                    <div v-on:click="displayAgregators(<?php echo $value->id;?>)" class="col-md-10">
                                        <span id="items<?php echo $value->id;?>"><?php echo ucfirst($value->username);?>

                            <?php }
                        }?>

I have searched for different solutions, but nothing directly related to the problem.
Hope you guys can help!

Body:
You can have some pre-defined colours,  and then randomly chose which colour to show

<div :class="randomColors"></div>

data(){
return {
      colors: [
        "red",
        "blue",
        "green",
        "indigo",
        "purple",
        "teal",
        "orange",
        "brown",
        "deep-orange",
        "blue-grey",
        "cyan"
      ],
      currentColor: ""
    }
},

 methods: {
    randomColors() {
      this.currentColor =
        this.colors[Math.floor(Math.random() * this.colors.length)];
    },
  }


问:
ASP.NET - TTL on Session Key-Value-Pairs (InProc)
Is there a sanctioned method for adding TTL to ASP.NET InProc Session State entries?

Example:

```<code>Session("First", 60) = "John"
Session("Adams", 500) = "Adams"
</code>```

答:
Out of the box, no there isn't. Individual Session State Key-Value-Pairs do not have any built-in method for adding a TTL or TTE.

Regarding the "global" InProc session state-timeout, it is controlled by a session state wide value configured in your web.config file (the timeout value in the /system.web/sessionState settings).

Additionally, whilst it may look like an attractive proposition to create your own session state provider, you couldn't use the Session property exposed by the page or controller code as this returns a HttpSessionState object. None of the methods, properties or indexers support having an extra parameter to specify individual session value timeouts.

You may consider doing the following:

Maintain an active session for each user:

Session("PersistMe") = true

Grab SessionID, and use it to store values in the ASP.NET Cache where you may utilize a TTL value.

Body:
Is there a sanctioned method for adding TTL to ASP.NET InProc Session State entries?

Example:

Session("First", 60) = "John"
Session("Adams", 500) = "Adams"


问:
PUT/POST in Laravel
I'm brand new to Laravel and am working my way through the [Laravel 6 from Scratch][1] course over at Laracasts. The course is free but I can't afford a Laracasts membership so I can't ask questions there.

I've finished Section 6 of the course, Controller Techniques, and am having unexpected problems trying to extend the work we've done so far to add a few new features. The course has students build pages that let a user show a list of articles, look at an individual article, create and save a new article, and update and save an existing article. The course work envisioned a very simple article containing just an ID (auto-incremented in the database and not visible to the web user), a title, an excerpt and a body and I got all of the features working for that, including updating an existing article and saving it.

The update form sets method to POST but then uses a @METHOD('PUT') directive to tell the browser that it is actually supposed to do a PUT. This worked perfectly in the original code. However, now that I've added two more fields to the form, when I click Submit after editing an existing record, the save fails with this message:

```<code>Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The PUT method is not supported for this route. Supported methods: GET, HEAD, POST.
http://localhost:8000/articles
</code>```

I don't understand why adding two fields to the form would cause this to break. Can someone enlighten me? I added the two new fields/columns to the migration and ran migrate:rollback and migrate. I've also added the new fields/columns to the fillable attribute and added validations for them in the ArticlesController.

Here is my routing:

```<code>Route::get('/articles', 'ArticlesController@index');
Route::post('/articles', 'ArticlesController@store');
Route::get('/articles/create', 'ArticlesController@create');
Route::get('/articles/{article}', 'ArticlesController@show');
Route::get('/articles/{article}/edit', 'ArticlesController@edit');
Route::put('/articles/{article}', 'ArticlesController@update');
//Route::delete('/articles/{article}', ArticlesController@destroy');
</code>```

This is my ArticlesController:

```<code><?php

namespace App\Http\Controllers;

use App\Article;
use Illuminate\Http\Request;

class ArticlesController extends Controller
{
public function index()
{
    $articles = Article::latest()->get();
    return view ('articles.index', ['articles' => $articles]);
}

public function show(Article $article)
{
    return view('articles.show', ['article' => $article]);
}

public function create()
{
    return view('articles.create');
}

public function store()
{
    //Stores a NEW article
    Article::create($this->validateArticle());
    return redirect('/articles');
}

public function edit(Article $article)
{
    return view('articles.edit', ['article' => $article]);
}

public function update(Article $article)
{
    //Updates an EXISTING article
    $article->update($this->validateArticle());
    return redirect('/articles/', $article->id);
}

public function validateArticle()
{
    return request()->validate([
        'title' => ['required', 'min:5', 'max:20'],
        'author' => ['required', 'min:5', 'max:30'],
        'photopath' => ['required', 'min:10', 'max:100'],
        'excerpt' => ['required', 'min:10', 'max:50'],
        'body' => ['required', 'min:50', 'max:500']
    ]);
}

public function destroy(Article $article)
{
    //Display existing record with "Are you sure you want to delete this? Delete|Cancel" option
    //If user chooses Delete, delete the record
    //If user chooses Cancel, return to the list of articles
}
}
</code>```

Here's my edit form, edit.blade.php:

```<code>@extends('layout')

@section('content')
<div id="wrapper">
<div id="page" class="container">
    <h1>Update Article</h1>
    <form method="POST" action="/articles">
        @csrf
        @method('PUT')
        <div class="form-group">
            <label class="label" for="title">Title</label>
            <div class="control">
                <input class="form-control @error('title') errorborder @enderror" type="text" name="title" id="title" value="{{ $article->title }}">
                @error('title')
                    <p class="errortext">{{ $errors->first('title') }}</p>
                @enderror
            </div>
        </div>
        <div class="form-group">
            <label class="label" for="author">Author</label>
            <div class="control">
                <input class="form-control @error('author') errorborder @enderror" type="text" name="author" id="author" value="{{ $article->author }}">
                @error('title')
                    <p class="errortext">{{ $errors->first('author') }}</p>
                @enderror
            </div>
        </div>
        <div class="form-group">
            <label class="label" for="photopath">Path to Photo</label>
            <div class="control">
                <input class="form-control @error('photopath') errorborder @enderror" type="text" name="photopath" id="photopath" value="{{ $article->photopath }}">
                @error('title')
                    <p class="errortext">{{ $errors->first('photopath') }}</p>
                @enderror
            </div>
        </div>
        <div class="form-group">
            <label class="label" for="excerpt">Excerpt</label>
            <div class="control">
                <textarea class="form-control @error('excerpt') errorborder @enderror" name="excerpt" id="excerpt">{{ $article->excerpt }}</textarea>
                @error('excerpt')
                    <p class="errortext">{{ $errors->first('excerpt') }}</p>
                @enderror
            </div>
        </div>
        <div class="form-group">
            <label class="label" for="body">Body</label>
            <div class="control">
                <textarea class="form-control @error('body') errorborder @enderror" name="body" id="body">{{ $article->body }}</textarea>
                @error('body')
                    <p class="errortext">{{ $errors->first('body') }}</p>
                @enderror
            </div>
        </div>
        <div class="control">
            <button class="btn btn-primary" type="submit">Submit</button>
        </div>
    </form>
</div>
</div>
@endsection
</code>```

```<code>Is there anything else you need to see?

  [1]: https://laracasts.com/series/laravel-6-from-scratch/episodes/33?autoplay=true
</code>```

答:
The route in the form for /articles, However your route for updating should be /articles/{article}

Try this:

```<code><form method="POST" action="/articles/{{ $article->id }}">
</code>```

Title: PUT/POST in Laravel

Body:
I'm brand new to Laravel and am working my way through the [Laravel 6 from Scratch][1] course over at Laracasts. The course is free but I can't afford a Laracasts membership so I can't ask questions there.

I've finished Section 6 of the course, Controller Techniques, and am having unexpected problems trying to extend the work we've done so far to add a few new features. The course has students build pages that let a user show a list of articles, look at an individual article, create and save a new article, and update and save an existing article. The course work envisioned a very simple article containing just an ID (auto-incremented in the database and not visible to the web user), a title, an excerpt and a body and I got all of the features working for that, including updating an existing article and saving it.

The update form sets method to POST but then uses a @METHOD('PUT') directive to tell the browser that it is actually supposed to do a PUT. This worked perfectly in the original code. However, now that I've added two more fields to the form, when I click Submit after editing an existing record, the save fails with this message:

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The PUT method is not supported for this route. Supported methods: GET, HEAD, POST.
http://localhost:8000/articles

I don't understand why adding two fields to the form would cause this to break. Can someone enlighten me? I added the two new fields/columns to the migration and ran migrate:rollback and migrate. I've also added the new fields/columns to the fillable attribute and added validations for them in the ArticlesController.

Here is my routing:

Route::get('/articles', 'ArticlesController@index');
Route::post('/articles', 'ArticlesController@store');
Route::get('/articles/create', 'ArticlesController@create');
Route::get('/articles/{article}', 'ArticlesController@show');
Route::get('/articles/{article}/edit', 'ArticlesController@edit');
Route::put('/articles/{article}', 'ArticlesController@update');
//Route::delete('/articles/{article}', ArticlesController@destroy');

This is my ArticlesController:

<?php

namespace App\Http\Controllers;

use App\Article;
use Illuminate\Http\Request;

class ArticlesController extends Controller
{
public function index()
{
    $articles = Article::latest()->get();
    return view ('articles.index', ['articles' => $articles]);
}

public function show(Article $article)
{
    return view('articles.show', ['article' => $article]);
}

public function create()
{
    return view('articles.create');
}

public function store()
{
    //Stores a NEW article
    Article::create($this->validateArticle());
    return redirect('/articles');
}

public function edit(Article $article)
{
    return view('articles.edit', ['article' => $article]);
}

public function update(Article $article)
{
    //Updates an EXISTING article
    $article->update($this->validateArticle());
    return redirect('/articles/', $article->id);
}

public function validateArticle()
{
    return request()->validate([
        'title' => ['required', 'min:5', 'max:20'],
        'author' => ['required', 'min:5', 'max:30'],
        'photopath' => ['required', 'min:10', 'max:100'],
        'excerpt' => ['required', 'min:10', 'max:50'],
        'body' => ['required', 'min:50', 'max:500']
    ]);
}

public function destroy(Article $article)
{
    //Display existing record with "Are you sure you want to delete this? Delete|Cancel" option
    //If user chooses Delete, delete the record
    //If user chooses Cancel, return to the list of articles
}
}

Here's my edit form, edit.blade.php:

@extends('layout')

@section('content')

Update Article

    <form method="POST" action="/articles">
        @csrf
        @method('PUT')

            Title

                <input class="form-control @error('title') errorborder @enderror" type="text" name="title" id="title" value="{{ $article->title }}">
                @error('title')

{{ $errors->first('title') }}

                @enderror

            Author

                <input class="form-control @error('author') errorborder @enderror" type="text" name="author" id="author" value="{{ $article->author }}">
                @error('title')

{{ $errors->first('author') }}

                @enderror

            Path to Photo

                <input class="form-control @error('photopath') errorborder @enderror" type="text" name="photopath" id="photopath" value="{{ $article->photopath }}">
                @error('title')

{{ $errors->first('photopath') }}

                @enderror

            Excerpt

                <textarea class="form-control @error('excerpt') errorborder @enderror" name="excerpt" id="excerpt">{{ $article->excerpt }}</textarea>
                @error('excerpt')

{{ $errors->first('excerpt') }}

                @enderror

            Body

                <textarea class="form-control @error('body') errorborder @enderror" name="body" id="body">{{ $article->body }}</textarea>
                @error('body')

{{ $errors->first('body') }}

                @enderror

            <button class="btn btn-primary" type="submit">Submit</button>

    </form>

@endsection

Is there anything else you need to see?

  [1]: https://laracasts.com/series/laravel-6-from-scratch/episodes/33?autoplay=true

Body:
The route in the form for /articles, However your route for updating should be /articles/{article}

Try this:

<form method="POST" action="/articles/{{ $article->id }}">


问:
Remove item from a list after I pick it
I want my code to pick a random number between 0 and 99, and then do it again 99 more times without picking a duplicate. I know how I'd do this in a very inefficient way (pick a random number and then check it against all numbers already picked, repicking if it is a duplicate).

I am sure that there is a better way, I just am not sure what to call the correct structure and thus I'm having a hard time getting the google results I need to figure this out.

What I think I need to do:

Build a "list" of 100 items, numbers 0 - 99.

Pick 1 item at random from that list, which will remove it from the list.

Pick from the entire list again, this time the list is 99 items in size.

Repeat until the list is empty

What is this called and what are the key concepts I need to understand?

答:
See 2-Dimensional array with different data type columns Generate 0 to 99 then randomise the table.

Arrays are all the same type.

Recordsets are tables. This reads a text file and puts a random number as a double and a string into each record.

```<code>Randomize
Set rs = CreateObject("ADODB.Recordset")
With rs
    .Fields.Append "RandomNumber", 4
    .Fields.Append "Txt", 201, 5000
    .Open
    Do Until Inp.AtEndOfStream
        .AddNew
        .Fields("RandomNumber").value = Rnd() * 10000
        .Fields("Txt").value = Inp.readline
        .UpDate
    Loop
    .Sort = "RandomNumber"
    Do While not .EOF
        Outp.writeline .Fields("Txt").Value
        .MoveNext
    Loop
End With
</code>```

Title: Remove item from a list after I pick it

Body:
See 2-Dimensional array with different data type columns Generate 0 to 99 then randomise the table.

Arrays are all the same type.

Recordsets are tables. This reads a text file and puts a random number as a double and a string into each record.

Randomize
Set rs = CreateObject("ADODB.Recordset")
With rs
    .Fields.Append "RandomNumber", 4
    .Fields.Append "Txt", 201, 5000
    .Open
    Do Until Inp.AtEndOfStream
        .AddNew
        .Fields("RandomNumber").value = Rnd() * 10000
        .Fields("Txt").value = Inp.readline
        .UpDate
    Loop
    .Sort = "RandomNumber"
    Do While not .EOF
        Outp.writeline .Fields("Txt").Value
        .MoveNext
    Loop
End With


问:
How to re-render Formik values after updated it - React Native?
I have a screen for update previously data "name, email, age, etc". at the first time I call a function that gets data from server name as getProfileData()

after user write the new data I send a POST request for that "update Profile"

and it's a success, but after that, I want to re-render this form with new data, So i call the getProfileData() function to get new data but it's not working to re-render Input Values!
it's just still with previous data

I also try with componentDidUpdate() but sadly not re-render :)

So how can i solve it?

Code

```<code>getProfileData = async () => {
    let USER_TOKEN =
      '....';
    let AuthStr = `Bearer ${USER_TOKEN}`;
    let response = await API.get('/profile', {
      headers: {Authorization: AuthStr},
    });
    let {
      data: {data},
    } = response;
    let password = '';
    let password_confirmation = '';
    let {name, email, avatar, age, gender, country_id} = data;
    let initialValues = [];
    initialValues.push({
      name,
      password,
      password_confirmation,
      email,
      avatar,
      age,
      gender,
      country_id,
    });
    this.setState({initialValues: initialValues, loading: false}, () =>
      reactotron.log(this.state.initialValues[0]),
    );
  };

  updateProfile = async value => {
    let USER_TOKEN =
      '....';
    let AuthStr = `Bearer ${USER_TOKEN}`;
    const headers = {
      'Content-Type': 'application/json',
      Authorization: AuthStr,
    };
    let response = await API.post('/update_profile', value, {
      headers: headers,
    });
    let {
      data: {data},
    } = response;
    alert(data);
    this.getProfileData(); // called
  };

 componentDidMount() {
    this.getCountryList();
    this.getProfileData();
  }
  componentDidUpdate(prevProps, prevState) {
    if (prevState.initialValues !== this.state.initialValues) {
      console.log('componentDidUpdate', this.state.initialValues);
      this.setState({initialValues: this.state.initialValues});
    }
  }
</code>```

UI

```<code><Formik
                  validationSchema={formSchema}
                  initialValues={this.state.initialValues[0]}
                  onSubmit={(values, actions) => {
                    this.updateProfile(values);
                    reactotron.log(values), actions.resetForm();
                  }}>
                  {({
                    handleChange,
                    handleBlur,
                    touched,
                    errors,
                    handleSubmit,
                    values,
                    setFieldValue,
                  }) => (
                    <View>
                      <Item style={styles.item} floatingLabel>
                        <Label style={styles.formLabel}>name</Label>
                        <Input
                          style={styles.value}
                          rounded
                          onChangeText={handleChange('name')}
                          onBlur={handleBlur('name')}
                          value={values.name}
                        />
                      </Item>
                      <Text style={styles.errorText}>
                        {touched.name && errors.name}
                      </Text>
                 </View>
             )}
 </Formik>
</code>```

答:
You can use enablereinitialize prop on formik.

```<code><Formik
  enableReinitialize
  ...
/>
</code>```

By default it is false, but if its true, what will happen is if you initialValues change, it will rerender.
So you can store your initialValues in state.

for example

```<code>state = {
  initialValues: { name: '', ...}
}
</code>```

and when you update the profile data just update that state.

```<code>setState({initialValues: newInitialValues })
</code>```

https://jaredpalmer.com/formik/docs/api/formik#enablereinitialize-boolean

Body:
I have a screen for update previously data "name, email, age, etc". at the first time I call a function that gets data from server name as getProfileData()

after user write the new data I send a POST request for that "update Profile"

and it's a success, but after that, I want to re-render this form with new data, So i call the getProfileData() function to get new data but it's not working to re-render Input Values!
it's just still with previous data

I also try with componentDidUpdate() but sadly not re-render :)

So how can i solve it?

Code

getProfileData = async () => {
    let USER_TOKEN =
      '....';
    let AuthStr = `Bearer ${USER_TOKEN}`;
    let response = await API.get('/profile', {
      headers: {Authorization: AuthStr},
    });
    let {
      data: {data},
    } = response;
    let password = '';
    let password_confirmation = '';
    let {name, email, avatar, age, gender, country_id} = data;
    let initialValues = [];
    initialValues.push({
      name,
      password,
      password_confirmation,
      email,
      avatar,
      age,
      gender,
      country_id,
    });
    this.setState({initialValues: initialValues, loading: false}, () =>
      reactotron.log(this.state.initialValues[0]),
    );
  };

  updateProfile = async value => {
    let USER_TOKEN =
      '....';
    let AuthStr = `Bearer ${USER_TOKEN}`;
    const headers = {
      'Content-Type': 'application/json',
      Authorization: AuthStr,
    };
    let response = await API.post('/update_profile', value, {
      headers: headers,
    });
    let {
      data: {data},
    } = response;
    alert(data);
    this.getProfileData(); // called
  };

 componentDidMount() {
    this.getCountryList();
    this.getProfileData();
  }
  componentDidUpdate(prevProps, prevState) {
    if (prevState.initialValues !== this.state.initialValues) {
      console.log('componentDidUpdate', this.state.initialValues);
      this.setState({initialValues: this.state.initialValues});
    }
  }

UI

<Formik
                  validationSchema={formSchema}
                  initialValues={this.state.initialValues[0]}
                  onSubmit={(values, actions) => {
                    this.updateProfile(values);
                    reactotron.log(values), actions.resetForm();
                  }}>
                  {({
                    handleChange,
                    handleBlur,
                    touched,
                    errors,
                    handleSubmit,
                    values,
                    setFieldValue,
                  }) => (
                    <View>
                      <Item style={styles.item} floatingLabel>
                        name
                        <Input
                          style={styles.value}
                          rounded
                          onChangeText={handleChange('name')}
                          onBlur={handleBlur('name')}
                          value={values.name}
                        />
                      </Item>
                      <Text style={styles.errorText}>
                        {touched.name && errors.name}
                      </Text>
                 </View>
             )}
 </Formik>

Body:
You can use enablereinitialize prop on formik.

<Formik
  enableReinitialize
  ...
/>

By default it is false, but if its true, what will happen is if you initialValues change, it will rerender.
So you can store your initialValues in state.

for example

state = {
  initialValues: { name: '', ...}
}

and when you update the profile data just update that state.

setState({initialValues: newInitialValues })

https://jaredpalmer.com/formik/docs/api/formik#enablereinitialize-boolean


问:
How to adjust cbar label position in sns.clustermap?
I'm ploting a seaborn clustermap and have problems to position the colorbar label. This is my code:

```<code>heatmap_plot = sns.clustermap(table, method=method, metric=metric,
                                  row_colors=row_colors,
                                  col_cluster=col_cluster, row_cluster=row_cluster,
                                  cmap=color_scheme,
                                  xticklabels=True, yticklabels=True,
                                  # linewidths=1,
                                  cbar_kws={'label': cbar_label})

plt.setp(heatmap_plot.cax.yaxis.get_label(), rotation=270)
</code>```

When I want to rotate cbar label text, it's overlapping with ticks and I have no idea how reposition it. Does anyone have an idea how to solve the problem?

答:
You could leave out the colorbar label from the main sns.clustermap call and then do

```<code>heatmap_plot.cax.set_title("my cbar label")
</code>```

Body:
I'm ploting a seaborn clustermap and have problems to position the colorbar label. This is my code:

heatmap_plot = sns.clustermap(table, method=method, metric=metric,
                                  row_colors=row_colors,
                                  col_cluster=col_cluster, row_cluster=row_cluster,
                                  cmap=color_scheme,
                                  xticklabels=True, yticklabels=True,
                                  # linewidths=1,
                                  cbar_kws={'label': cbar_label})

plt.setp(heatmap_plot.cax.yaxis.get_label(), rotation=270)

When I want to rotate cbar label text, it's overlapping with ticks and I have no idea how reposition it. Does anyone have an idea how to solve the problem?

Body:
You could leave out the colorbar label from the main sns.clustermap call and then do

heatmap_plot.cax.set_title("my cbar label")


问:
Multi-endpoint Kestrel configuration with different TLS certificates serves the wrong certificate
I am trying to set up the Kestrel server in an ASP.NET Core MVC-based service app in Linux environment through its appsettings.json config file so that it has exactly two endpoints, both using HTTPS, but each with a different certificate. One endpoint listens on 0.0.0.0, the other only on localhost. The service serves as the host for IdentityServer4. The intended runtime environment for the server will be a Docker container, which is a part of a multiservice-based system, currently run as a docker-compose cluster.

I have studied the official documentation at https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2#endpoint-configuration and assumed it should be easily achievable. I have created a self-signed root CA certificate and generated two certificates signed by the root. One of them has the Common Name set to the name the container will have in the cluster and is intended for secure communication with the external environment. The other certificate has the CN set to localhost and is used because the server has multiple controllers that will be available from outside and they all will transform incoming requests and forward to a special internal controller that will handle them. (I realize that is a little paranoid of me, but that's beside the point.)

I have tried to configure Kestrel so that the main endpoint uses the default certificate and the localhost endpoint uses the ad-hoc certificate, i.e. like so:

```<code>  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://+:2051"
      },
      "HttpsLocalhost": {
        "Url": "https://localhost:2052",
        "Certificate:": {
          "Path": "path/to/localhost-dev.pfx",
          "Password": "password"
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "path/to/identity-api-dev.pfx",
        "Password": "password"
      }
    }
  }
</code>```

which appears to be the correct configuration as per the docs, which say that the server requires a default certificate to be defined if configuring HTTPS explicitly.

The outward facing controller uses a lazily initialized HttpClient, whose BaseAddress property is initialized on the first received request with the URL of the localhost endpoint. That URL is determined trivially with this method

private string GetIdentityServiceHostAndPort()
{
    IServerAddressesFeature addresses = Server.Features.Get<IServerAddressesFeature>();

    // Get the first that uses HTTPS and is on localhost
    foreach (string url in addresses.Addresses)
    {
        if (url.StartsWith("https://localhost"))
        {
            return url;
        }
    }

    throw new ArgumentException("Could not determine identity service's host/port, is it listening on localhost using HTTPS?");
}
```

<p>The address returned by the above method is then passed to the following method that initializes the controller's <code>HttpClient</code> instance with it and also queries the IS4's OpenID configuration endpoint for the discovery document and uses that to further initialize the controller:</p>

<pre class="lang-cs prettyprint-override"><code>private static async Task InitializeTokenEndpointHttpClientAsync(string baseAddress)
{
    TokenEndpointClient = new HttpClient();
    TokenEndpointClient.BaseAddress = new Uri(baseAddress);

    HttpResponseMessage response = await TokenEndpointClient.GetAsync(".well-known/openid-configuration");
    string content = await response.Content.ReadAsStringAsync();
    if (response.StatusCode != HttpStatusCode.OK)
    {
        throw new InvalidOperationException("Error querying IdentityServer for discovery document: " + content);
    }

    DiscoveryDocument document = JsonConvert.DeserializeObject<DiscoveryDocument>(content);
    Uri fullTokenEndpointUri = new Uri(document.token_endpoint);
    TokenEndpointPath = fullTokenEndpointUri.LocalPath;
}
</code>```

Since I have already spent a sizable amount of time trying to debug this issue, I have made sure that the server is configured to listen both on any address with one port and on localhost with another. The GetIdentityServiceHostAndPort() method does indeed return the correct URL.

Now, the problem I am facing is that the request for the discovery document in the method above dies with

```<code>System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
</code>```

Obviously, the certificate validation process failed, which seems suspicious to me, since the request was supposed to go to the endpoint that does have a certificate with CN=localhost set.

When I tried manually requesting the discovery document with

```<code>curl -g 'https://localhost:2052/.well-known/openid-configuration'
</code>```

I got this message

```<code>curl: (60) SSL: certificate subject name 'identity.api' does not match target host name 'localhost'
</code>```

I do not understand why the server would try to send this certificate. I know it is the configured default, but there is also the certificate expressly defined for the localhost endpoint and I would expect that one to be used in this case.

I am sure I am missing something but as I said, I have already spent several hours trying to find the culprit, so I will be very grateful for any input.

答:
Just to make this clear and embarrass myself in front of the entire developer world at the same time, the issue was that I was constantly overlooking a typo in the Kestrel configuration section. There is an extraneous colon in the Certificate key string in the HttpsLocalhost subsection, which I could not spot if my life depended on it.

Thankfully, it did not, and of course the configuration worked after this fix.

Body:
I am trying to set up the Kestrel server in an ASP.NET Core MVC-based service app in Linux environment through its appsettings.json config file so that it has exactly two endpoints, both using HTTPS, but each with a different certificate. One endpoint listens on 0.0.0.0, the other only on localhost. The service serves as the host for IdentityServer4. The intended runtime environment for the server will be a Docker container, which is a part of a multiservice-based system, currently run as a docker-compose cluster.

I have studied the official documentation at https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2#endpoint-configuration and assumed it should be easily achievable. I have created a self-signed root CA certificate and generated two certificates signed by the root. One of them has the Common Name set to the name the container will have in the cluster and is intended for secure communication with the external environment. The other certificate has the CN set to localhost and is used because the server has multiple controllers that will be available from outside and they all will transform incoming requests and forward to a special internal controller that will handle them. (I realize that is a little paranoid of me, but that's beside the point.)

I have tried to configure Kestrel so that the main endpoint uses the default certificate and the localhost endpoint uses the ad-hoc certificate, i.e. like so:

  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://+:2051"
      },
      "HttpsLocalhost": {
        "Url": "https://localhost:2052",
        "Certificate:": {
          "Path": "path/to/localhost-dev.pfx",
          "Password": "password"
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "path/to/identity-api-dev.pfx",
        "Password": "password"
      }
    }
  }

which appears to be the correct configuration as per the docs, which say that the server requires a default certificate to be defined if configuring HTTPS explicitly.

The outward facing controller uses a lazily initialized HttpClient, whose BaseAddress property is initialized on the first received request with the URL of the localhost endpoint. That URL is determined trivially with this method

private string GetIdentityServiceHostAndPort()
{
    IServerAddressesFeature addresses = Server.Features.Get<IServerAddressesFeature>();

    // Get the first that uses HTTPS and is on localhost
    foreach (string url in addresses.Addresses)
    {
        if (url.StartsWith("https://localhost"))
        {
            return url;
        }
    }

    throw new ArgumentException("Could not determine identity service's host/port, is it listening on localhost using HTTPS?");
}

The address returned by the above method is then passed to the following method that initializes the controller's HttpClient instance with it and also queries the IS4's OpenID configuration endpoint for the discovery document and uses that to further initialize the controller:

private static async Task InitializeTokenEndpointHttpClientAsync(string baseAddress)
{
    TokenEndpointClient = new HttpClient();
    TokenEndpointClient.BaseAddress = new Uri(baseAddress);

    HttpResponseMessage response = await TokenEndpointClient.GetAsync(".well-known/openid-configuration");
    string content = await response.Content.ReadAsStringAsync();
    if (response.StatusCode != HttpStatusCode.OK)
    {
        throw new InvalidOperationException("Error querying IdentityServer for discovery document: " + content);
    }

    DiscoveryDocument document = JsonConvert.DeserializeObject<DiscoveryDocument>(content);
    Uri fullTokenEndpointUri = new Uri(document.token_endpoint);
    TokenEndpointPath = fullTokenEndpointUri.LocalPath;
}

Since I have already spent a sizable amount of time trying to debug this issue, I have made sure that the server is configured to listen both on any address with one port and on localhost with another. The GetIdentityServiceHostAndPort() method does indeed return the correct URL.

Now, the problem I am facing is that the request for the discovery document in the method above dies with

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

Obviously, the certificate validation process failed, which seems suspicious to me, since the request was supposed to go to the endpoint that does have a certificate with CN=localhost set.

When I tried manually requesting the discovery document with

curl -g 'https://localhost:2052/.well-known/openid-configuration'

I got this message

curl: (60) SSL: certificate subject name 'identity.api' does not match target host name 'localhost'

I do not understand why the server would try to send this certificate. I know it is the configured default, but there is also the certificate expressly defined for the localhost endpoint and I would expect that one to be used in this case.

I am sure I am missing something but as I said, I have already spent several hours trying to find the culprit, so I will be very grateful for any input.