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

allow '1' or true for acceptance validation. #18439

Merged
merged 1 commit into from Jan 12, 2015
Merged

allow '1' or true for acceptance validation. #18439

merged 1 commit into from Jan 12, 2015

Conversation

xlgmokha
Copy link
Contributor

While pairing on a project this morning we were confused as to why this code kept failing:

# user.rb
class User < ActiveRecord::Base
  attr_accessor :terms_and_conditions
  validates_acceptance_of :terms_and_conditions
end
describe User do
  it "is valid" do
    user = User.new(terms_and_conditions: true)
    expect(user).to be_valid
  end
end

After looking through the source we found that the default value is: "1". This seems nonintuitive. To make this test pass we had to change our code to this:

# user.rb
class User
  attr_accessor :terms_and_conditions
  validates_acceptance_of :terms_and_conditions, accept: true
end

This Pull Request changes the default accept from "1" to ["1", true]. Allowing you to specify an array of options. It supports single values as well for backwards compatibility.

/cc @speasley

Topic.validates_acceptance_of(:terms_of_service)

assert Topic.new(terms_of_service: true).valid?
assert Topic.new(terms_of_service: "1").valid?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to test this here, it's already covered elsewhere.

@sgrif
Copy link
Contributor

sgrif commented Jan 10, 2015

This needs a changelog entry. I have no opinions on the feature itself, I'll let someone else decide whether or not to merge.

@xlgmokha
Copy link
Contributor Author

Thank you @sgrif.

@@ -20,6 +20,11 @@ def setup!(klass)
klass.send(:attr_reader, *attr_readers)
klass.send(:attr_writer, *attr_writers)
end

def acceptable_option?(value)
accept_options = [options[:accept]].flatten
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we just do Array(options[:accept]) instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me. I'll update shortly. :)
On Jan 10, 2015 5:07 PM, "Sean Griffin" notifications@github.com wrote:

In activemodel/lib/active_model/validations/acceptance.rb
#18439 (diff):

@@ -20,6 +20,11 @@ def setup!(klass)
klass.send(:attr_reader, *attr_readers)
klass.send(:attr_writer, *attr_writers)
end
+

  •  def acceptable_option?(value)
    
  •    accept_options = [options[:accept]].flatten
    

How about we just do Array(options[:accept]) instead?


Reply to this email directly or view it on GitHub
https://github.com/rails/rails/pull/18439/files#r22763094.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All done. Should I inline the method as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to you.

@@ -3,12 +3,12 @@ module ActiveModel
module Validations
class AcceptanceValidator < EachValidator # :nodoc:
def initialize(options)
super({ allow_nil: true, accept: "1" }.merge!(options))
super({ allow_nil: true, accept: ["1", true] }.merge!(options))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add "true" in the array. e.g. ["1", true, "true"]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if that would lead to a possible explosion of options. i.e. "True", "TRUE"

Currently, if you need to add additional accept options you can do so.

class User < ActiveRecord::Base
  validates_acceptance_of :terms_and_conditions, accept: ["True", "TRUE", "true"]
end

I would like to keep this change minimal, as I believe TrueClass should be one of the default accept options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somebody might using "true" in their test cases. Then what is the purpose for this patch?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @mokhan, just true is sufficient.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kuldeepaggarwal - the point is now you can specify an array of acceptable values.

If people were using 'true' before their tests weren't passing, so that's a non issue. Now you will be able to accept ["1", true, "true"] as you suggest by configuring it in the class:

class User < ActiveRecord::Base
  validates_acceptance_of :terms_and_conditions, accept: ["1", true, "true"]
end

You can have it accept anything in the array where before an array wasn't possible, just a single value.

sgrif added a commit that referenced this pull request Jan 12, 2015
allow '1' or true for acceptance validation.
@sgrif sgrif merged commit 72570ea into rails:master Jan 12, 2015
@rails rails locked and limited conversation to collaborators Jan 23, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants