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.
Related
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
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
I'm learning rails with the book Agile Web development with Rails 4e. It uses the following so far as our product model (adapted from a scaffold):
class Product < ActiveRecord::Base
attr_accessible :description, :image_url, :price, :title
validates :description, :title, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{\.(gif|jpg|png)$}i,
message: 'Must be a valid URL for a gif, png, or jpg..'
}
end
I'm wondering why it tests first for the presence of :image_url, but then in the tertiary validation to make sure the image url is valid, it allows for blank responses which contradicts the first validation. I don't understand why this is supposed to work as is.
As an additional question, if the image_url is empty, how can I test if it is empty in my code? (e.g. in the product view to display a default image.)
Model validations are tested in isolation. A model is valid if and only if it passes validation for each validates statement independently.
It's probably bad-form, and evidently confusing for that allow_blank: true to be in the 4th validation, but that only applies to that single statement. The model must pass all validations to be considered valid, so the 1st statement merely imposes a tighter restriction than the 4th.
A final point, note that presence tests for non-nilness, whereas blank is defined as nil or the empty string. It is therefore possible to be both present and blank; e.g. image_url = ''. However, it remains the case that validations are tested separately in isolation.
I think maybe you are confused about the validation code? I'm a noob, and this is probably not entirely accurate: the validates keyword doesn't test for presence, it starts a block that you use to specify your validations.
As is, your code will validate the :image_url according to your specifications if it exists. If you took out allow_blank: true, then a nonexistent or blank :image_url would fail the validations.
I'm new to Rails as well and am using the same book. My understanding is that in order to stop the validation returning two errors immediately against validation (i.e. one if the field is blank and one if it doesn't have a correct file extension) it must allow_blank for the file format.
The best way I can explain it is to suggest removing the allow_blank: true code and trying to submit the description form again.
You should then see that you get both the validation errors for the field being blank and the file format being wrong.
The allow_blank therefore tells the validation to only error on the file format once the field is no longer blank.
Confused me as well which is why I ended up here!
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
I am developing Rails 3 app.
I would like to validate the "Cake" model's "size" attribute input field to only allow user to input +1,-1,+10,-10 and +25,-25, nothing else.
I use the following validation to validate "size":
class Cake < ActiveRecord::Base
validates_format_of :size, :with => /^[-+]?(1|10|25)$/, :message=>'size not allowed.'
...
end
(The "size" attribute in my database "cakes" table is a "double" type.)
In the UI, I always get fail message of the validation even I input 1 or 10 or 25 or +1 or whatever. Why my validation does not pass even the value is right?
I'm not sure if validating an Integer with a Regex works.
You could try validates_inclusion_of :size, :in=>[-1,+1,-10,+10,-25,+25], :message=>'size not allowed.'