Boolean checkbox needs to be accepted all the time even when checked - ruby-on-rails

I've put a validation in a checkbox for tos_agreements, but now, even if it's checked, it still gives me the error "Tos Agreements need to be accepted".
What I have is:
1.) I've added :tos_agreements to Devise permitted params in Application Controller
2.) I've validated like this:
validates_acceptance_of :tos_agreement, :allow_nil => false, :accept => true
Any idea? Thanks!

i usually do this with an attr_accessor(of course in the model of the user):
attr_accessor :tos_agreement
validates :tos_agreement, acceptance: true
this will validate that the checkbox tos_agreement will be checked, regards

Related

Simple-Form and required fields: doesn't treat as required if condition added to validation

Simple-Form automatically detects whether there is a validates :xxx, presence: true validation, and displays the field as a required one (e.g. with an asterisk appended to the label).
validates :parent, presence: true
This results in:
Interestingly, as soon as I add a condition to this validation...
validates :parent, presence: true, if: -> { true }
...it doesn't do this no more:
Is this a bug or a feature?
This is the expected behavior, validations are only run when you save the object to the db, so you have no way of knowing whether the lambda returns true or not until then. Of course in your case it always returns true, but imagine you have a time constraint in your lambda or some other more complex condition, e.g.
...., -> { Time.zone.now > Date.new(2017, 1, 1) }
Maybe when you create the object for the form this returns false, but when the form is actually submitted and saved to the db enough time had passed for it to return true.
So there is no way for simple_form to know when the form is created whether the field is required or not.
You could call it a feature, since it's deliberate. If you look at the gem code (especially at calculate_required and conditional_validators?) you'll notice that if the presence validator has a condition, like if or unless, the field is no longer marked as required.
I solved like this for :terms being a checkbox element:
validates :terms, presence: true, acceptance: true
With this, it validates at form level for checking that 'term' checkbox is submitted only after it's checked. Hope it helps someone in the future.
Simple form validations don't work if you have conditions in your validations.
This is intentional as you can put whatever you want in an :if or :unless and calling this could cause unintended side effects.
source: https://github.com/heartcombo/simple_form/issues/322

Rails validates acceptance not validating

I would like to simply validate a terms checkbox on my form. I have implemented the folowing:
http://guides.rubyonrails.org/active_record_validations.html#acceptance
class User < ActiveRecord::Base
validates :terms, acceptance: true
end
I have stripped the form back to the checkbox only for debugging purposes.
Regardless of the entry passed the :terms does not validate. The form parameters appear to being passed correctly.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"+1dzwEMajQN4cL7KdGjlIw2kFSyVk/36eAhNhdydUXhLfzyT7LnCiUGdfzYt3hD/dD7evIVMiVWePv+7p+scyA==", "user"=>{"terms"=>"1"}, "commit"=>"Register"}
When I update the validation to the following I receive an error stating "Terms must be accepted" regardless of the terms value submitted. This leads me to believe the value from the form is not being passed to the validation.
validates :terms, acceptance: true, :allow_nil => false
OK...
The problem was that the validation helper validates the contents of the row within the table before saving. For this to trigger I needed to assign the ":terms" value to the model for validation.
I was only passing the params hash with the "terms" item within it expecting that to be validated.

Adding TOS agreement checkbox with Devise

We're using devise for our members. We've added a tos_agreement field (boolean) to our member schema, and we added it to views/devise/registrations/new.html.haml.
In the Member model, we have a validation rule as follows:
validates_acceptance_of :tos_agreement, :allow_nil => false,
:accept => true
It works fine - if you don't accept the TOS, you can't register.
However, the problem comes with editing your settings. If you go to /members/edit you get the form where you can change your email address or password. There's no field for the TOS agreement since this shouldn't be changeable at this point. However, when you make a change (eg. change your password) and submit the form, it returns an error message that the TOS agreement can't be false.
How can we tell it never to attempt to modify the TOS agreement after the first registration?
Edit: so I think the fundamental problem is that we had :tos_agreement in our attr_accessible, which was a very bad idea now I think of it. But if we remove it, how do we modify Devise to accept the parameter and do something with it even though it's not mass-assignable?
You can pass an :on => :create option to the validator so that it's only checked on signup:
validates_acceptance_of :tos_agreement, :allow_nil => false, :accept => true, :on => :create

Check if an input box exists in rails

I have to check if confirm_password input box exists in form.If it exists,
I need to do this:
validates :password,:confirmation=>true
else
set confirmation to false.
Detail explanation for the problem:
I'm using rails client_side_validation gem which converts models validation into javascript form validation.
There is a little problem with this as login and sign up belongs to same table both of them have one Model. Now when I'm adding this in model for validation:
validates :password,:confirmation=>true
It will not let me to login as validation will become false as there is no confirm_password input box on login.It will only work on signup.
Assuming a model User add #user.is_signup = true to the signup action in users_controller. In your User model add attribute_accessor :is_signup and validates :confirm_password, :confirmation => true, :if => :is_signup.
In your signup form you could have a hidden field that gets passed in the form. If the attribute is present and returns true then you validate the presence of the password confirmation.
Signup form, somewhere inside the form tags:
<%= form.hidden_field :is_signup, true %>
Model:
attribute_accessor :confirm_password
attribute_accessor :is_signup
validates :confirm_password, :presence => true, :if => :validate_confirm_password?
def validate_confirm_password?
is_signup
end

preventing rails validation based on previous validation

I have a model with 2 validations on the 'name' attribute. It goes something like this:
validates :name, :uniqueness => true
validate do
errors.add(:name, "is dumb") if name_is_dumb?
end
I don't want the 2nd validation to run if the first validation fails (the name is not unique).
What's the best and cleanest way to do this?
According to the documentation:
Callbacks are generally run in the
order they are defined, with the
exception of callbacks defined as
methods on the model, which are called
last.
So the following snippet should work:
validates :name, :uniqueness => true
validate do
errors.add(:name, "is dumb") unless errors[:name].nil?
end

Resources