trailblazer / reform

Form objects decoupled from models.
https://trailblazer.to/2.1/docs/reform.html
MIT License
2.49k stars 184 forks source link

`self` in default value for properties is broken when Reform 2.6 is with trailblazer-context #530

Closed samstickland closed 3 years ago

samstickland commented 3 years ago

Complete Description of Issue

The value of self in a property block is resolving to the Class of the form (not the instance) when reform 2.6 is used in a project that also has trailblazer-context included.

This does not happen with reform 2.5 plus trailblazer-context, or with reform 2.6 just used by itself

Steps to reproduce


class MyForm < Reform::Form
  property :my_property, virtual: true, default: -> { puts self; my_method }

  def my_method
    :foobar
  end
end

MyForm.new(nil).my_property

Expected behavior

self should resolve to the instance of the form. The default value of my_property should be :foobar

> MyForm.new(nil).my_property
#<MyForm:0x00007f90bcd722c0>
=> :foobar

Actual behavior

self resolves to the MyForm class, not the instance, meaning the method cannot be called:

irb(main):009:0> my_form = MyForm.new(nil).my_property
MyForm
Traceback (most recent call last):
        3: from (irb):8
        2: from (irb):8:in `new'
        1: from (irb):2:in `block in <class:MyForm>'
NameError (undefined local variable or method `my_method' for MyForm:Class)
Did you mean?  method

System configuration

Reform version: 2.6.0

yogeshjain999 commented 3 years ago

@samstickland I tried to reproduce it by creating new rails app but couldn't reproduce it.

Both gems are independent of each other, I wonder how they can cause such issue. How're they being dependent in your case ? Could you please create a reproducible test for it ?

samstickland commented 3 years ago

@yogeshjain999 As requested here is a repo that demonstrates the problem:

https://github.com/samstickland/reform-trailblazer-context-issue

Github defaulted the primary branch to be called 'main' btw.

There's a form in app/forms/my_form.rb and a failing test for that form, using minitest: bundle exec rake test

The test will pass if you do either of these things:

samstickland commented 3 years ago

So weird.. now I can't reproduce the problem locally in that repo anymore, but a moment ago I had the issue! Here's the test output I had:

~/development/rails-6.1.3.2*$ be rake
Run options: --seed 39558

# Running:

E

Error:
MyFormTest#test_sets_a_default_value_for_my_property_from_my_method:
NameError: undefined local variable or method `my_method' for MyForm:Class
    app/forms/my_form.rb:2:in `block in <class:MyForm>'
    test/form/my_form_test.rb:5:in `new'
    test/form/my_form_test.rb:5:in `block in <class:MyFormTest>'

rails test test/form/my_form_test.rb:4

Finished in 0.555248s, 1.8010 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
samstickland commented 3 years ago

@yogeshjain999 I had to add some more trailblazer gems to the Gemfile to make the problem come back. I'm pushed that to the repo, I'm not sure which of the gems that has been added is causing the interaction that leads to the problem.

yogeshjain999 commented 3 years ago

@samstickland The issue was in trailblazer-activity where it was using old trailblazer-context gem to load Trailblazer::Option, causing the conflict.

Release trailblazer-activity-0.12.2 fixes it 🍻