Coder Social home page Coder Social logo

dry-rails's People

Contributors

arielvalentin avatar blelump avatar citizen428 avatar deepj avatar diegotoral avatar dry-bot avatar gotar avatar holywalley avatar jandudulski avatar kalys avatar olleolleolle avatar radar avatar rinaldifonseca avatar skryukov avatar solnic avatar timriley avatar zlw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dry-rails's Issues

Integration between AM:V and dry-schema

I made something like this to automatically import dry-schema (contract) from my Custom class to a Rails model, so every tool (gem) that require model validation automatically use schema

class Vehicle < ApplicationRecord
  validates_with CustomValidator, type: :vehicle
end

class CustomValidator < ActiveModel::Validator
  include Namespace::Import[
    vehicle_contract: 'vehicles.contracts.new',
  ]

  def validate(record)
    validator = case options[:type]
                when :vehicle then vehicle_contract.(record.attributes)
                end

    unless validator.success?
      validator.errors.to_h.each do |key, errors|
        errors.each do |error|
          record.errors[key] << error
        end
      end
    end
  end
end

>> v = Vehicle.new
>> v.valid?
=> false
>> v.errors
=> #<ActiveModel::Errors:0x000055bae1ce8500 @base=#<Vehicle id: nil, company_id: nil, vin: nil, created_at: nil, updated_at: nil, deleted_at: nil, leaser: nil, leasing_end: nil, bik: nil, cost: nil, plate: nil, data: nil, rental_price: nil, vehicle_category_id: nil, retribution_price: nil, gearbox: "auto", vehicle_brand_id: nil, engine: "Petrol", fuel: "Petrol">, @messages={:company=>["must exist"], :vehicle_category=>["must exist"], :vehicle_brand=>["must exist"], :company_id=>["must be filled"], :vehicle_category_id=>["must be filled"], :vehicle_brand_id=>["must be filled"], :vin=>["must be filled"], :plate=>["must be filled"], :leaser=>["must be filled"], :leasing_end=>["must be filled"], :bik=>["must be filled"], :cost=>["must be filled"], :rental_price=>["must be filled"], :retribution_price=>["must be filled"]}, @details={:company=>[{:error=>:blank}], :vehicle_category=>[{:error=>:blank}], :vehicle_brand=>[{:error=>:blank}]}>>>

Works like a charm, so maybe will be useful for someone, plus I think It's quire easy to add to dry-rails itself.

Using dry-system's settings raises am undefined method `env' for Dry::Configurable::Config exception

Describe the bug

Trying to define settings from dry-system (https://dry-rb.org/gems/dry-system/0.17/settings/) using config/system/boot raises an exception:

dry-configurable-0.11.5/lib/dry/configurable/config.rb:106:in `method_missing': undefined method `env' for #<Dry::Configurable::Config:0x00005599da1e52e8>

To Reproduce

https://github.com/Szeliga/dry-rails-test this repo implements a basic app
https://github.com/Szeliga/dry-rails-test/blob/master/config/initializers/system.rb types module definition
https://github.com/Szeliga/dry-rails-test/blob/master/config/system/boot/settings.rb settings component setup

Running rails c reproduces the error

Expected behavior

It should not raise an exception and create an importable settings component

Your environment

  • Affects my production application: NO
  • Ruby version: 2.7.1
  • OS: Linux 5.5.13-arch2-1

cannot define multiple schemas in one controller (safe params)

Describe the bug

If schema is defined more than once, it overwrite safe_params. So safe_params are only available and works for last defined schema.

To Reproduce

class UsersController < ApplicationController
  schema(:show) do
    required(:id).value(:integer)
  end

  schema(:new) do
    required(:id).value(:integer)
  end

  def show
    if safe_params.success?
      render json: {id: safe_params[:id], name: "Jane"}
    else
      render json: {errors: safe_params.errors.to_h}
    end
  end

  def new
    if safe_params.success?
      render json: {id: safe_params[:id], name: "Jane"}
    else
      render json: {errors: safe_params.errors.to_h}
    end
  end
end

Expected behavior

safe params works for both defined schema, currently second works, but for :show safe_params are just nil

Add description

I know it's a brand new project, but a description of what it does (or intends to) would be nice.

Edit: a roadmap would be good too ๐Ÿ˜„

Application container not to be finalized in test env

Components get booted immediately, before test setup is allowed to run. This means that items registered in the container from these boot files cannot be stubbed, before they are injected into other components that require them.

For example, the following setup will not work:

# config/system/boot/event.rb
MyApp::Container.boot(:event) do
  start do
     register('event_bus', MyEventBus.new)
  end
end

# config/system/boot/component.rb
MyApp::Container.boot(:component) do |container|
  use :event
  
  start do
    container['event_bus'].subscribe(MyListener.new, to: [MyEvent])
  end
end

# spec/rails_helper.rb
before do
  # Both :event and :component are already started at this point,
  # so this setup has no effect at all if container memoizes the registered items

  MyApp::Container.start(:event)
  MyApp::Container.stub('event_bus', TestDoubleEventBus.new)
  MyApp::Container.start(:component)
end

This behavior was already present in Dry::System::Rails, where the components had to be booted manually.

Resources

https://discourse.dry-rb.org/t/different-behavior-in-finalizing-container-between-dry-rails-and-dry-rails/1129

Unable to change config.root

This dry-rb/dry-system-rails#16 had broken an ability to set config.root under rails initializer

# config/initializers/system.rb
Dry::System::Rails.container do
  config.root = ::Rails.root.join('app')
end

Then run in rails console

> MyApp::Container.config.root
=> #<Pathname:/path/to/my_app>

# should be
=> #<Pathname:/path/to/my_app/app>

The reason is default_options are merged after container.class_eval(&@container_block) evaluated.
https://github.com/dry-rb/dry-system-rails/blob/master/lib/dry/system/rails.rb#L43

Application container not reloading nested dependencies in Rails Console on Rails 6?

Describe the bug

Forgive me, I am new to the dry-* community, and have been working in the background on converting our current service objects to the dry ecosystem.

A problem I've having is that I'm having issues reloading our container in a rails console. If I put any files I'd like to include in the container at the root level of the auto_register path it reloads just fine, but if I nest it under another folder, it does not reload.

To Reproduce

# in initializers/system.rb
Dry::Rails.container do
  auto_register!('app/operations')
end

# in `app/operations/concepts/demonstrate_bug.rb`
module Concepts
  class DemonstrateBug
    def demonstrate_bug
      puts 'Demonstrated'
    end
  end
end

And in a Rails console (our app is called Phoenix):

[11] pry(main)> Phoenix::Container.resolve('concepts.demonstrate_bug').demonstrate_bug
Demonstrated
=> nil

So far so good, but when I change something and then reload:

# in `app/operations/concepts/demonstrate_bug.rb`
module Concepts
  class DemonstrateBug
    def demonstrate_bug
      puts 'Demonstrates potential pug'
    end
  end
end
[12] pry(main)> Phoenix::Container.resolve('concepts.demonstrate_bug').demonstrate_bug
Demonstrated
=> nil
[13] pry(main)> reload!
Reloading...
=> true
[14] pry(main)> Phoenix::Container.resolve('concepts.demonstrate_bug').demonstrate_bug
Demonstrated
=> nil

Expected behavior

I would expect changing the file and then reloading the Rails console would change the message in the Rails console to Demonstrates potential bug but it doesn't. Again I am new to this ecosystem so I may be missing something

Your environment

  • Affects my production application: NO
  • Ruby version: ruby 2.7.0p0
  • OS: macOS Catalina

Dry-Rails + ActionController::API

Since dry-rails include controller only in the ApplicationController, it's not possible to use safe_params and other methods if you are working in a Rails API when your controller inherits from ActionController::API.
@solnic said that this should be supported OOTB.

Maybe:

start do
  ActionController::Base.include(Dry::Rails::Features::ControllerHelpers)
  ActionController::API.include(Dry::Rails::Features::ControllerHelpers)
end

Injection issue in rails 7 & ruby 3.1

We have more than 20 rails app using rails 6 & below and ruby 2.7 & below, there are implemented service pattern using dry injection, it is broken on rails 7 & ruby 3.1

I'm getting an error looks like

Started POST "/api/v1/posts/search.json" for ::1 at 2022-02-16 00:26:43 +0000
  
ArgumentError (wrong number of arguments (given 1, expected 0)):
  
actionpack (7.0.2.2) lib/action_controller/metal.rb:150:in `initialize'
actionpack (7.0.2.2) lib/action_dispatch/routing/url_for.rb:108:in `initialize'
dry-auto_inject (0.9.0) lib/dry/auto_inject/strategies/kwargs.rb:71:in `block (2 levels) in define_initialize_with_splat'
dry-auto_inject (0.9.0) lib/dry/auto_inject/strategies/kwargs.rb:22:in `new'
dry-auto_inject (0.9.0) lib/dry/auto_inject/strategies/kwargs.rb:22:in `block (2 levels) in define_new'
actionpack (7.0.2.2) lib/action_controller/metal.rb:251:in `dispatch'
actionpack (7.0.2.2) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (7.0.2.2) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (7.0.2.2) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (7.0.2.2) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (7.0.2.2) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (7.0.2.2) lib/action_dispatch/routing/route_set.rb:850:in `call'
rack (2.2.3) lib/rack/etag.rb:27:in `call'
rack (2.2.3) lib/rack/conditional_get.rb:40:in `call'
rack (2.2.3) lib/rack/head.rb:12:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.2.2) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.2.2) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/show_exceptions.rb:26:in `call'
railties (7.0.2.2) lib/rails/rack/logger.rb:36:in `call_app'
railties (7.0.2.2) lib/rails/rack/logger.rb:25:in `block in call'
activesupport (7.0.2.2) lib/active_support/tagged_logging.rb:99:in `block in tagged'
activesupport (7.0.2.2) lib/active_support/tagged_logging.rb:37:in `tagged'
activesupport (7.0.2.2) lib/active_support/tagged_logging.rb:99:in `tagged'
railties (7.0.2.2) lib/rails/rack/logger.rb:25:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.3) lib/rack/runtime.rb:22:in `call'
activesupport (7.0.2.2) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/server_timing.rb:20:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/static.rb:23:in `call'
rack (2.2.3) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.2.2) lib/action_dispatch/middleware/host_authorization.rb:137:in `call'
railties (7.0.2.2) lib/rails/engine.rb:530:in `call'
puma (5.6.2) lib/puma/configuration.rb:252:in `call'
puma (5.6.2) lib/puma/request.rb:77:in `block in handle_request'
puma (5.6.2) lib/puma/thread_pool.rb:340:in `with_force_shutdown'
puma (5.6.2) lib/puma/request.rb:76:in `handle_request'
puma (5.6.2) lib/puma/server.rb:441:in `process_client'
puma (5.6.2) lib/puma/thread_pool.rb:147:in `block in spawn_thread'

To Reproduce

  1. create a new app using rails 7 with api mode
  2. create a service with a single method so we have this structure under app directory
app/
  controllers/
    api/
      v1/
  ...
  ...
  services/
    v1/
module V1
    class PostService
        def search(keyword)
             "OK"
        end
    end
end
  1. create a container class named di_container.rb on lib/marka/ directory and register and initialize the PostService class
require 'dry-container'
require 'dry-auto_inject'

module Marka
    class DiContainer
        extend Dry::Container::Mixin
        
        register :v1_post_service do
            V1::PostService.new
        end
    end
    INJECT = Dry::AutoInject(Marka::DiContainer)
end
  1. create a new controller called posts_controller under app/controllers/api/v1/ directory, and try to inject the method which registered on Marka module
require 'marka/di_container'
module Api
  module V1
    class PostsController < ApplicationController
      include Marka::INJECT[:v1_post_service]

      def search
         render json: { status: "OK" }
      end
    end
  end

Expected behavior

Upgrade our apps to rails 7 using the same pattern.

My environment

  • Affects my production application: YES due to development issue
  • Ruby version: 3.1
  • Rails 7.0.2.2
  • OS: MacOS Mojave 10.14.6
  • dry-auto_inject (0.9.0)
  • dry-container (0.9.0)

stakeoverflow question :
https://stackoverflow.com/q/71131422/2858044

Key-based Import doesn't get stubbed

Describe the bug

When a dependency is imported via key-based argument, stubbing doesn't affect it's resolving.

I've made a sample app that reproduces the issue: https://github.com/mgpnd/import_example

Here's the most important snippets from the app:

# Operation that will be imported and stubbed
module Example
  class Show
    def call
      self.class.name
    end
  end
end
class ExampleController < ApplicationController
  include ImportExample::Import[
    show_example: "example.show"
  ]

  def index
    @auto_imported = show_example.()
    @manually_resolved = ImportExample::Container["example.show"].()
  end
end

/spec/controllers/example_controler_spec.rb:

RSpec.describe ExampleController, type: :controller do
  describe '#index' do
    subject { get :index, params: { format: 'text/hmtl' } }

    ...
    
    before do
      # Stubbing is enabled somewhere else so this part works properly
      ImportExample::Container.stub('example.show', -> { 'operation stub' })
    end

    # Fails, @auto_imported == "Example::Show"
    it 'calls auto imported stub' do
      subject
      expect(assigns(:auto_imported)).to eq('operation stub')
    end

    # Passes, @manually_resolved == "operation stub"
    it 'calls manually resolved stub' do
      subject
      expect(assigns(:manually_resolved)).to eq('operation stub')
    end
  end
end

To Reproduce

  1. Define a dependency via auto_inject Import with key-based argument
  2. Stub the dependency in any test

Expected behavior

The dependency resolved to provided stub.

Your environment

  • Affects my production application: NO
  • Ruby version: 2.7

I've tried to reproduce the issue with plain dry-auto_inject and with basic dry-system, but it doesn't appear there, in both gems importing works properly so I'm reporting it here.

Add application template

The gem should provide a rails application template that would simply provide the following things:

  • Gemfile should include dry-rails with the current version
  • config/initializers/system.rb should be created with the following content for a good start:
    Dry::Rails.container do
      # cherry-pick features
      config.features = %i[application_contract]
    
      # enable auto-registration in the lib dir
      # config.auto_register << 'lib'
    
      # enable auto-registration of custom components
      # auto_register!('app/serializers', strategy: :namespaced)
    en
  • ...more?

Container constant to be configurable

In my current application, there is an ActiveRecord model named Container. This is unfortunately in conflict with dry-rails while booting and failed with undefined method features for Container since

app_namespace.const_get(:Container)
loads model class.

Examples

Dry::Rails.container do
  config.container_constant = 'MyContainer'
end

Please update `dry-system` to `~> 1.0`

Describe the bug

dry-rails requires dry-system in ~> 0.27 version.

spec.add_runtime_dependency "dry-system", "~> 0.27", ">= 0.27.2"

There is a bug in dry-logic < 1.5 which crashes irb/rails console. And to use dry-logic 1.5 we need dry-system ~> 1.0...

`fetch': key not found: :path (KeyError)

Describe the bug

Running Rails tests or server produces the following error fetch': key not found: :path (KeyError).

I'm using dry-rails but the issue seems to stem from lib/dry/system.rb:23 (dry-system)

Backtrace

> bundle exec rails test
/usr/local/bundle/gems/dry-system-0.23.0/lib/dry/system.rb:23:in `fetch': key not found: :path (KeyError)
	from /usr/local/bundle/gems/dry-system-0.23.0/lib/dry/system.rb:23:in `register_provider'
	from /usr/local/bundle/gems/dry-rails-0.4.0/lib/dry/rails/components.rb:5:in `<top (required)>'
	from /usr/local/bundle/gems/dry-rails-0.4.0/lib/dry/rails.rb:5:in `require'
	from /usr/local/bundle/gems/dry-rails-0.4.0/lib/dry/rails.rb:5:in `<top (required)>'
	from /usr/local/bundle/gems/dry-rails-0.4.0/lib/dry-rails.rb:3:in `require'
	from /usr/local/bundle/gems/dry-rails-0.4.0/lib/dry-rails.rb:3:in `<top (required)>'
	from /usr/local/bundle/gems/bundler-2.3.5/lib/bundler/runtime.rb:60:in `require'
	from /usr/local/bundle/gems/bundler-2.3.5/lib/bundler/runtime.rb:60:in `block (2 levels) in require'
	from /usr/local/bundle/gems/bundler-2.3.5/lib/bundler/runtime.rb:55:in `each'
	from /usr/local/bundle/gems/bundler-2.3.5/lib/bundler/runtime.rb:55:in `block in require'
	from /usr/local/bundle/gems/bundler-2.3.5/lib/bundler/runtime.rb:44:in `each'
	from /usr/local/bundle/gems/bundler-2.3.5/lib/bundler/runtime.rb:44:in `require'
	from /usr/local/bundle/gems/bundler-2.3.5/lib/bundler.rb:176:in `require'
	from /app/config/application.rb:7:in `<top (required)>'
	from /app/config/environment.rb:2:in `require_relative'
	from /app/config/environment.rb:2:in `<top (required)>'
	from /app/test/test_helper.rb:12:in `require_relative'
	from /app/test/test_helper.rb:12:in `<top (required)>'
	from /app/test/controllers/api/v1/some_controller_test.rb:2:in `require'
	from /app/test/controllers/api/v1/some_controller_test.rb:2:in `<top (required)>'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/test_unit/runner.rb:47:in `require'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/test_unit/runner.rb:47:in `block in load_tests'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/test_unit/runner.rb:47:in `each'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/test_unit/runner.rb:47:in `load_tests'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/test_unit/runner.rb:40:in `run'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/commands/test/test_command.rb:33:in `perform'
	from /usr/local/bundle/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
	from /usr/local/bundle/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
	from /usr/local/bundle/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/command/base.rb:87:in `perform'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/command.rb:48:in `invoke'
	from /usr/local/bundle/gems/railties-7.0.1/lib/rails/commands.rb:18:in `<top (required)>'
	from bin/rails:4:in `require'
	from bin/rails:4:in `<main>'
ERROR: 1

To Reproduce

I'm using a super basic docker + rails repo and am able to recreate issue once I add gem 'dry-rails' to the Gemfile. Rails server and testing stops working. See Repo here: https://github.com/joshmfrankel/rails-7-docker

Expected behavior

Expect tests and server to execute and dry-system to properly build

My environment

  • Ubuntu 20.04.3
  • Dry-rails - 0.4.0
  • Ruby - 3.1.0
  • Rails - 7.0.1
  • Minitest 5.15.0
  • Nodejs - 16.13.1
  • Docker 20.10.12
  • docker-compose 1.29.2

Transforming request parameters for the `safe_params` feature

Feature request:

Rails sends form parameters for date_select as...

{:"date(1i)"=>2021, :"date(2i)"=>5, :"date(3i)"=>20}

I want to validate this against my schema.

required(:date).filled(:date)

Currently I need to do some pre-transforming of the parameters for this to work, having a built-in way to do this in Rails would be really nice.


Background:

This was talked about here: https://www.reddit.com/r/ruby/comments/niceer/dryschema_and_dryvalidation_gems/
and here: https://dry-rb.zulipchat.com/#narrow/stream/191662-general/topic/dry-schema/near/239935781

Dependency is not registered when namespace is non-standard named

Describe the bug

I have a namespace which looks like (example) CloudNATS. This is a namespace of Rails application declared in config/application.rb as well.

When I tried to import a dependecy, I got

Dry::Container::Error (Nothing registered with the key :http)

To Reproduce

# app/operations/create_user
class CreateUser
  include CloudNATS::Import[:http]
end
# lib/cloudnats/http.rb
module CloudNATS
  class HTTP
  end
end

Expected behavior

The dependency is successfully imported without any exception. My namespace would

Your environment

  • Affects my production application: NO
  • Ruby version: 2.7.1
  • OS: macOS

ApplicationContract is not defined. Rails 7.1.2

Describe the bug

Hey, I ran into an issue when with a clean setup I don't have defined ApplicationContract.
This is my first time using dry-rails, maybe I'm doing something wrong? Demo app link is below.

UPD:

  • checked with latest version from github
  • checked with cherry-picking the feature
    result is the same

To Reproduce

$ rails new myapp --minimal
$ bundle add dry-rails
$ bin/rails c
irb(main):001> ApplicationContract
(irb):1:in `<main>': uninitialized constant ApplicationContract (NameError)

Demo app

My environment

  • Ruby version: 3.1.2
  • Rails version: 7.1.2
  • OS: Debian bookworm in docker & macos 13.4.1
  • dry-rails 0.7.0
  • dry-system 1.0.1
  • dry-schema 1.13.3
  • dry-validation 1.10.0

Confusing docs about throw(:abort)

Docs example:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  before_action do
    if safe_params && safe_params.failure?
      render(:error, errors: safe_params.errors.to_h) and throw(:abort)
    end
  end
end

I'm just starting a new project and giving a try to this feature but I was surprised by UncaughtThrowError: uncaught throw :abort error. Digging deeper into Rails docs:

The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a "before" filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter, they are also cancelled.

AFAIK throw(:abort) is only about ActiveRecord callbacks, not controller filters (aka before/after action). Actually, link about the feature from dry-rails docs also discusses only callbacks.

Got FrozenError after dry-core upgrade to 0.9.1

Describe the bug

The ActiveSupport::Dependencies.autoload_paths is frozen but still some autoload paths is attached.

debug gem trace

DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:61 [] receives #<< (Array#<<) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/actionmailer-7.0.4/lib/action_mailer/railtie.rb:72
DEBUGGER (trace/object) #th:1 #depth:61 [] receives #freeze (Kernel#freeze) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/application/finisher.rb:20
DEBUGGER (trace/object) #th:1 #depth:61 [] receives #uniq (Array#uniq) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/application/finisher.rb:21
Tapioca attempted to load the Rails application after encountering a `config/application.rb` file, but it failed. If your application uses Rails please ensure it can be loaded correctly before generating RBIs.
uninitialized constant Dry::Validation::Contract::ClassInterface

      extend ClassInterface
             ^^^^^^^^^^^^^^
Continuing RBI generation without loading the Rails application.
Done
DEBUGGER (trace/object) #th:1 #depth:94 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:95 [] receives #inspect (Array#inspect) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574

To Reproduce

Reference this file to remove dry-core version pin and update it to reproduce
https://github.com/BasalticStudio/new-era/blob/e52e10fae29dda85d0c635a4da6421ba176c78cd/Gemfile

Unable to reproduce in other projects that have the same version (without dry-rails) and I am tracing it.

Updated - 1

ruby debug gem with:

b ActiveSupport::Dependencies.autoload_paths do: info

When #freeze is called, the Rails seems to continue running the initializer again.

Updated - 2

It is caused by dry-validation ~> 1.9.0 cannot correct load the module

/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/dry-validation-1.9.0/lib/dry/validation/contract.rb:47:in `<class:Contract>': uninitialized constant Dry::Validation::Contract::ClassInterface (NameError)

      extend ClassInterface
             ^^^^^^^^^^^^^^

If downgraded to 1.8.1 other dry gem have same issue.

Expected behavior

The initializer should not be called after the freeze.

My environment

  • Affects my production application: YES
  • Ruby version: 3.0.4 or 3.1.2 are breaks
  • OS: macOS/Linux

safe_params are empty in ApplicationController before_action

Describe the bug

# frozen_string_literal: true

class UsersController < ApplicationController
  before_action do
    if safe_params&.failure?
      head 422
    else
      head 200
    end
  end

  schema(:show) do
    required(:id).value(:integer)
  end

  def show
  end
end

This code will always return 200, because:

lib/dry/rails/features/safe_params.rb

def schema(*actions, &block)
  schema = Dry::Schema.Params(&block)

  actions.each do |name|
    schemas[name] = schema
  end

  before_action(:set_safe_params, only: actions)

  self
end
before_action(:set_safe_params, only: actions)

this before_action is put in queue after before_action in UsersController. This might not be a problem in UsersController, I can just move my before_actions bellow the schema definition, however, if I'm trying to do something like here: https://dry-rb.org/gems/dry-rails/0.1/#safe-params and provide params check in ApplicationController I'll face the problem when I always get nil by calling safe_params.

To Reproduce

Use the code above

Expected behavior

safe_params is available in any callback

Your environment

  • Affects my production application: NO
  • Ruby version: 2.6.5
  • Rails version: 6.0.2.2
  • OS: Mac OS

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.