Skip to content

Loading…

Conditional Validations error #992

Closed
willcosgrove opened this Issue · 5 comments

2 participants

@willcosgrove

I'm getting an error on any validations that use either if: or unless:. Specifically the error I'm getting is wrong number of arguments (1 for 0) which is occurring at inputs/base/validations.rb#L39.

The lambda trying to be called is from the validation in this User class:

class User < ActiveRecord::Base
  has_one :employee_invitation
  validates_presence_of :first_name, :last_name, :username, unless: -> { unregistered_employee? }
  # ...
  private

  def unregistered_employee?
    employee_invitation.present? && !employee_invitation.accepted
  end
end

I was able to fix the problem like this: cf795cb

But I didn't know where or how exactly to build a failing test. I'm also running Ruby 2.1.0p-0 and Rails 4.0.1, which I didn't know if this library is officially supporting.

Either way, I figured I'd post my problem/solution here too see if anyone else has run into this problem.

@willcosgrove

After taking another look at the formtastic source, I realized I could also change my validation conditional like so

validates_presence_of :first_name, :last_name, :username, :timer_format_preference, unless: ->(user) { user.send(:unregistered_employee?) }

Which would also fix the problem. Is that the Rails Way™? I didn't think you were supposed to specify any arguments like that.

@justinfrench

If it can be done both ways in Rails (and one isn't deprecated), we should be supporting both.

I think adding a spec to any input spec (string?) in any place would be a great start if you're up for it? Any failing test will help me get progress.

@justinfrench justinfrench referenced this issue
Closed

Prep for 2.3.0.rc4 #1028

6 of 8 tasks complete
@justinfrench

@willcosgrove I have had a look into this. Would be great if you could confirm this is still an issue against master, as this particular piece of code has moved on a little. Here's the relevant piece of code:

result = if conditional.respond_to?(:call) && conditional.arity > 0
  # A
  conditional.call(object)
elsif conditional.is_a?(::Symbol) && object.respond_to?(conditional)
  # B
  object.send(conditional)
else
  # C
  conditional
end

If you have code like this, you end up at A:

unless: -> (user)  { user.whatever? }

If you have code like this, you end up at C:

unless: -> { whatever? }

I think maybe this form would also work for you in this case (you'd end up at `B'):

unless: -> { :whatever? }

Until recently (before 1e45bf1, which is how the code looked when you reported this), all Procs would end up at A, but now it seems like it's possible to have a Proc which never gets called. I was able to repeat your particular error message in a spec by reverting that change, but with 1e45bf1 in play, it seems the goal posts have moved a little.

I think we need a new 4th conditional in here to allow for Procs with an arity of 0. Perhaps something like this:

result = if conditional.respond_to?(:call) && conditional.arity > 0
  # A
  conditional.call(object)
elsif conditional.respond_to?(:call) && conditional.arity == 0
  # new code goes here
elsif conditional.is_a?(::Symbol) && object.respond_to?(conditional)
  # B
  object.send(conditional)
else
  # C
  conditional
end

I'm not sure of the exact code that's needed. If object.instance_exec(&conditional) works for you, that'd be a great start. I've pushed up a new branch 992-validation-conditional with my work so far. If you could bundle your app against this version of Formtastic and let me know how this is working for you, that'd be great.

I'm really keen to get a new version out, so I'd appreciate you helping out sooner rather than later if possible.

@justinfrench

Fixed by #1032

@justinfrench

I've also cherry-picked a 1.8.7 compatible version of #1032 into 2.3-stable, but I found that I couldn't get this form to pass in a spec:

unless: -> { whatever? }

I couldn't find any documentation for this form in Rails 3 guides or APIs, so I've removed the failing spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.