apotonick / disposable

Decorators on top of your ORM layer.
MIT License
171 stars 39 forks source link

Module that has 'unnest' throws an error if included more than once #81

Open ivked85 opened 3 years ago

ivked85 commented 3 years ago

I have a Reform::Form::Module where I'm using unnest. If I try to include it more than once I get an error on startup: gems/disposable-0.4.7/lib/disposable/twin/property/unnest.rb:14:in `unnest': undefined method `[]' for nil:NilClass (NoMethodError)

A setup similar to this:

module Contract::Component
  module Foo
    include Reform::Form::Module

    property :foo do
      property :bar
    end

    unnest :bar, from: :foo
  end
end

module Contract
  class Create < Reform::Form
    include Component::Foo
  end
end

module Contract
  class Update < Reform::Form
    include Component::Foo
  end
end

This is the relevant part of the code in disposable

    def unnest(name, options)
      from = options.delete(:from)
      # needed to make reform process this field.

      options = definitions.get(from)[:nested].definitions.get(name).instance_variable_get(:@options) # FIXME.
      options = options.merge(virtual: true, _inherited: true, private_name: nil)

      property(name, options)
      delegates from, name, "#{name}="
    end

Since unnest is a class method, options.delete(:from) will actually delete the key from the method argument itself, causing each subsequent call to fail. Changing that line to from = options[:from] seems to fix the issue for me, without introducing any noticeable side-effects.

yogeshjain999 commented 3 years ago

Makes sense.

@apotonick I think we should not mutate the options ? We can now access from as a kwarg too.

def unnest(name, from:, **options)
  ...
end