开发者

Accept terms of use rails

开发者 https://www.devze.com 2023-03-12 03:22 出处:网络
What is the best way to add a check for ac开发者_如何学运维cepting terms of use in a rails app?

What is the best way to add a check for ac开发者_如何学运维cepting terms of use in a rails app?

I can't seem to get validates_acceptance_of working quite right. I added a bool to my user model (was that necessary?). And then have a checkbox that returns either true/false.

I feel like I'm just making a silly little mistake. Any ideas?


In your model,

validates_acceptance_of :terms

If you're using attr_accessible in your model then make sure you also add,

attr_accessible :terms

In your view,

<%= form_for @user do |f| %>
  ...
  <%= f.check_box :terms %>
  ...
<% end %>

There is no need for an extra column in the users table unless you plan on denying access to users who have not accepted the terms of service, which won't exist since they can't complete registration in the first place.


This is a working Rails 4 solution:

Terms of service doesn't need to be a column in the database

Form

= f.check_box :terms_of_service

models/user.rb

validates :terms_of_service, acceptance: true

And most important, devise will sanitize your parameters and terms of service will be removed from the submitted params. So:

registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController
  before_filter :configure_permitted_parameters

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:full_name,
        :email, :password, :password_confirmation, :terms_of_service)
    end 
  end
end


This is a working solution for Rails-6.1 (I18n) + Devise-4.8.0 + SimpleForm. No need to add a column in the "users" table in DB.

View

 <% label_str = t('read_html', mylink: link_to(t('terms'), '/a/b/c')) %>
 <%= f.input :terms_of_service, label: label_str, as: :boolean, checked: false %>

Or, if you use Indo-European languages only, you can make it a little more simple, like:
label_str = (t('agree_html')+link_to(t('terms'), '/a/b/c')+'.').html_safe

/app/models/user.rb

attr_accessor :terms_of_service
validates_acceptance_of :terms_of_service, on: :create
validates_presence_of   :terms_of_service, on: :create

/app/controllers/application_controller.rb

Devise::ParameterSanitizer::DEFAULT_PERMITTED_ATTRIBUTES[:sign_up] << :terms_of_service
 # see /vendor/bundle/ruby/*/gems/devise-*/lib/devise/parameter_sanitizer.rb

Explanation

In the User model, on: create guarantees it is read only in creation. If you need to reevaluate the condition in updating, too, specify it accordingly, like on: %i(create update).

In the User model, I add validates_presence_of to play safe. The reason is, validates_acceptance_of will not be executed when the parameter terms_of_service is nil, in which case validates_presence_of will catch it and set an error. Admittedly, if the data are always submitted via the web-interface you have built AND your implementation is working perfectly, the value should be always either true or false and never be nil. So, validates_presence_of should not be necessary in this sense. It does no harm, though (except you'd need to be a little careful in manual user creation, bypassing the web-interface, such as from the Console).

The last one is neccesary for use with Devise for the same reason as in the answer by @vladCovaliov; that is, to prevent Devise from sanitizing your custom parameter, which is not a column in the database table. The one-liner in the example above can be stated in any files as long as you are sure it is read at the run-time and after Devise Ruby code. application_controller.rb is one of the sure places (though I guess there is a better-fitting place). Make sure the sentence is put out of the class ApplicationController block.

0

精彩评论

暂无评论...
验证码 换一张
取 消