Acceptance of Terms and Conditions - ruby-on-rails

I know that there have been a few other posts on this topic, but I have tried their solutions and they don't work. I have a devise user model, and this model has a boolean called :terms_and_conditions. I want to prevent a user from signing up on my website unless they have checked this terms and conditions box. By checking the box, the user's boolean attribute should be set to true. With my current code, a user can sign up without checking the box, and checking the box does not affect the boolean field. How can I fix this?
devise/registrations/new.html.erb:
<div class="checkbox">
<label>
<%= f.check_box :terms_and_conditions %><strong> I accept the terms and conditions<strong>
</label>
</div>
models/user.rb:
validates_acceptance_of :terms_and_conditions

in models/user.rb:
validates_presence_of :terms_and_conditions

set validates :terms_of_service, acceptance: true, and see if that fixes your problem. read more about it at rails guide here

Related

Do form validation that does not use database

I have a form and I have made some inputs required. After submitting the form that value will be sent to an API. I know that the validations are put into model file but since I do not have a database, how can I use the rails validation?
Right now I am validating the code inside a controller using if else.
if !params[:groups][:name].blank? && !params[:groups][:make].blank? && !params[:groups][:model].blank? && !params[:groups][:firmware].blank?
This does the work but it is not very elegant.
Take a look at ActiveModel, it lets you do "model things" without the database. There were some limitations that made me not use it in the end (I think related to associations) but for simple stuff it's great (and it's a part of how ActiveRecord works.
Example code from docs
class Person
include ActiveModel::Model
attr_accessor :name, :age
validates :name, :age, presence: true
end
this is easy. On the form input fields that you NEED, add required: true For example:
<%= form.for #something do |f| %>
<%= f.text_field :title, placeholder: 'Title', required: true %>
<% end %>
The user gets an error if the required fields are not filled out correctlty.
Is this what you mean?
Justin
EDIT
I guess I would look at using the gem
client_side_validations
Let us know how you go

Test with capybara and simple form won't check the checkbox

I'm having quite a bit of trouble checking a terms of service box from simple_form in my capybara/rspec test.
Here is my validation:
validates :terms_of_service, acceptance: true, allow_nil: false
If I remove allow_nil: false then the specs all pass even if the box isn't checked. If I leave it, the validation causes the specs to fail.
Here is the code creating the form/checkbox:
= f.label :terms_of_service, "I agree to the #{link_to 'Terms of Service', terms_of_service_path, :target => "_blank"}".html_safe
= f.check_box :terms_of_service
The resulting html:
<label for="candidate_terms_of_service">I agree to the Terms of Service</label>
<input name="candidate[terms_of_service]" type="hidden" value="0">
<input id="candidate_terms_of_service" name="candidate[terms_of_service]" type="checkbox" value="1">
My attempts in my test which I've tried individually:
page.find_by_id("candidate_terms_of_service").check
find(:xpath, "//*[#id='candidate_terms_of_service']").set(true)
find(:css, "#candidate_terms_of_service").set(true)
check 'candidate[terms_of_service]'
check 'I agree to the Terms of Service'
find('#candidate_terms_of_service').check
And resulting failure:
Failure/Error: let(:candidate) { create(:candidate) }
ActiveRecord::RecordInvalid:
Validation failed: Terms of service must be accepted
How do I check this box?
This particular simple_form field gave me a lot of grief, and while I found several different ways mentioned to query and set it, none of them worked (some mentioned in this issue, others from Capybara issues).
I found the following to actually work with a simple_form boolean with RSpec:
find(:xpath, "//label[#for='candidate_terms_of_service']").click
For the sake of completeness considering the different webdrivers and total solutions given, here are the other solutions found but resulted in invalid selector errors. The input selector would actually error about the inability to check simple_form's default hidden input; this error makes sense, the label is the visible and top-most element.
find('#active_form_terms_of_service').set(true)
# or select by label
find('label[for=active_form[terms_of_service]').click
# and select by label and value if multiple boxes
# with the same ID (not sure why this would happen)
find("label[value='1']").click
# or select the input with xpath
find(:xpath, "//input[value='1']").set(true)
Try:
find('#candidate_terms_of_service').check

Rails 4: How to display fields with error in red?

First question: how to validate a model relation and mark it in form when validation failed.
I have a subject model:
class Subject < ActiveRecord::Base
belongs_to :semester
validates_presence_of :semester
end
In my view (form):
<%= select_tag :semester, options_from_collection_for_select(#semesters,"id","name") %>
The validates_presence_of works fine. But when the validation fails (user forgot to enter semester ). The semester input is not marked in red.
Second question: how to validate an input field.
In my view, I also have a university input field, but model subject has no relationship with university, no field university in subject table. So how to validate it and mark it in red.
Thanks in advance.
If you want to get the fields with error displayed in red "out of the box", you must use a form builder. The code will looks like f.select ... instead of using select_tag.
With the form builder, the fields with errors are created inside a <div class="field_with_errors">...</div>. The css file generated by scaffolding displays these fields in red; if you're not using it, you must add the css rules to your css.
# app/models/subject.rb
class Subject < ActiveRecord::Base
belongs_to :semester
validates :semester, :university, presence: true # new syntax http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates
end
# app/views/subjects/_form.html.erb
<%= form_for #subject do |f| %>
Semestr: <%= f.collection_select :semester_id, Semestr.all, :id, :name, prompt: true %>
University: <%= f.text_field :univercity %>
<% end %>
For more information about building forms in rails (with validations enabled) you could find there http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html
Those "red errors" that you hope for are probably coming from a form helper gem like formtastic, feel free to check that out.
I have literally no idea what your second question is asking, but if you're looking for a custom validation. Check out the rails docs on them for help.
If you'd like more help, (please) edit your question to be more clear (thanks)

How to simply validate a checkbox in rails

How do you simply validate that a checkbox is checked in rails?
The checkbox is for a end user agreement. And it is located in a modal window.
Lets say i have the checkbox:
<%= check_box_tag '' %>
Where and how should i validate this?
I have seen most posts about checkbox validation in rails here, but none of them suit my needs.
Adding
validates :terms_of_service, :acceptance => true
to your model should do it. Look here for more details and options.
However, if accepting the terms is not part of a form for your model, you should use client-side validations, i.e. JavaScript, like this (in jQuery):
function validateCheckbox()
{
if( $('#checkbox').attr('checked')){
alert("you have to accept the terms first");
}
}
You can add a script file to your view like this:
<%= javascript_include_tag "my_javascipt_file" %>
and trigger the function on click:
<%= submit_tag "Submit", :onclick: "validateCheckbox();" %>
EDIT: you can assign an id to your checkbox like this: check_box_tag :checkbox. The HTML will look like this: <input id="checkbox" See these examples for more options.
I was able to skip the jQuery portion and get it validation to work with this questions help. My method is below, I'm on Rails 5.1.2 & Ruby 2.4.2.
Put this code in your slim, erb or haml; note syntax may differ slightly in each.
The line below was specifically for slim.
f.check_box :terms_of_service, required: true
I used a portion of kostja's code suggestion in the model.
validates :terms_of_service, :acceptance => true
Adding on to what has been said already, if you want to add a custom error message, you can add the following to your form:
f.input :terms_of_service, as: :boolean
and then add the following to your model:
validates :terms_of_service, acceptance: { message: "must be accepted"}
Error messages will start with the field name by default followed by your custom message (e.g. Terms of service [CUSTOM MESSAGE]). Something I also found useful was to include a link to the terms of service in the label so users can easily access it to see what they are agreeing to:
f.input :terms_of_service, as: :boolean, label: "I agree to the #{link_to "terms of service", [TERMS AND CONDITIONS PATH]}".html_safe

Rails Model: How to make an attribute protected once it's created?

I was just wondering: How can i make an attribute "write once" ?
To be more precise, I'm using Devise and I want the user to be able to register with this email but then, once it's done, I want this email locked.
I read that forms can easily be bypass, so I want to make sure my model does that.
Also, i'm using in one of my form that: <%= f.email_field :email, :id => "email", :disabled => "disabled" %>
Is there any risks that an user can modify his email after being registered?
Thanks for your answers!
attr_readonly allows setting a value at creation time, then prevents modifying it on updates.
class MyModel < ActiveRecord::Base
attr_readonly :email
end

Resources