Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form inheritance raises for validates_with when not wrapped in a validation group #15

Open
RKushnir opened this issue Aug 5, 2016 · 0 comments

Comments

@RKushnir
Copy link

RKushnir commented Aug 5, 2016

Steps to reproduce

Having the following form declaration:

class FooForm < Reform::Form
  property :foo
  validates_with DoesntMatterValidator, attributes: [:foo]
end

class DoesntMatterValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value); end # whatever here
end

Call Class.new(FooForm).

Expected behavior

A child class of FooForm created.

Actual behavior

Exception ArgumentError: :attributes cannot be blank raised.

System configuration

Reform-rails version: 0.1.3 (also, applies to master as of now)
Reform version: 2.2.1

Full Backtrace of Exception

ArgumentError: :attributes cannot be blank
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activemodel-4.2.6/lib/active_model/validator.rb:139:in `initialize'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activemodel-4.2.6/lib/active_model/validations/with.rb:93:in `new'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activemodel-4.2.6/lib/active_model/validations/with.rb:93:in `block in validates_with'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activemodel-4.2.6/lib/active_model/validations/with.rb:92:in `each'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activemodel-4.2.6/lib/active_model/validations/with.rb:92:in `validates_with'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/reform-2.2.1/lib/reform/validation.rb:27:in `block in validates_with'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/reform-2.2.1/lib/reform/validation.rb:15:in `instance_exec'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/reform-2.2.1/lib/reform/validation.rb:15:in `validation'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/declarative-0.0.8/lib/declarative/heritage.rb:18:in `call!'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/declarative-0.0.8/lib/declarative/heritage.rb:11:in `block in call'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/declarative-0.0.8/lib/declarative/heritage.rb:11:in `each'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/declarative-0.0.8/lib/declarative/heritage.rb:11:in `call'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/disposable-0.3.2/lib/disposable/twin.rb:19:in `inherited'
from (irb):4:in `initialize'
from (irb):4:in `new'
from (irb):4
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/console.rb:110:in `start'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/console.rb:9:in `start'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:68:in `console'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /Users/apotonick/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'

Helpful info

The problem is activemodel mutates arguments that you pass to validates_with, so while usually this doesn't matter, because they aren't used anymore, reform accidentally reuses them.
First, validations are initialized for the class itself, which works fine. But it fails on the second pass, which happens if you inherit from a form class(which TRB does).

Here's the culprit:

validation(:default, inherit: true) { validates_with *args, &block }

The block captures the args. Note, this doesn't happen if you declare the validation group explicitly, because then args are not captured.

A quick solution would be to use args.dup, what do you think, @apotonick ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant