issue with rails terms of service validation - ruby-on-rails-4

I am experiencing an issue with validating our terms of service checkbox using devise and simple form.
User Model
validates_acceptance_of :terms, :allow_nil => false, :message => :terms_not_accepted, :on => :create
Registration View
= f.label :terms, "I agree to the #{link_to 'Terms of Service', "http://britevid.com/terms_of_service",:remote => true}.".html_safe, {class: "checkbox inline"}
= f.check_box :terms
= f.button :submit, 'Sign up', :class => 'btn btn-success'
Application Controller
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:first_name, :last_name, :company, :phone_number, :website, :content_description, :address, :city, :state, :zip_code, :country, :paypal_email, :time_zone, :email, :current_password, :password, :password_confirmation, :terms)}
devise_parameter_sanitizer.for(:account_update) {|u| u.permit(:first_name, :last_name, :company, :phone_number, :website, :content_description, :address, :city, :state, :zip_code, :country, :paypal_email, :time_zone, :email, :current_password, :password, :password_confirmation)}
end
Started POST "/users" for 127.0.0.1 at 2014-03-21 07:19:24 -0500
Processing by RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "user"=>{"first_name"=>"jeff", "last_name"=>"smith", "email"=>"jeffsmith#lol.com", "company"=>"test", "phone_number"=>"453234562", "website"=>"", "content_description"=>"test", "address"=>"1st ave", "city"=>"big city", "state"=>"California", "country"=>"United States", "zip_code"=>"095610", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "terms"=>"0"}, "commit"=>"Sign up"}
(0.2ms) BEGIN
User Exists (0.1ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'jeffsmith#lol.com' LIMIT 1
(0.1ms) ROLLBACK
Rendered devise/registrations/new.html.haml within layouts/pages (46.2ms)
Rendered layouts/shared/_external_header.html.haml (0.4ms)
Completed 200 OK in 157ms (Views: 67.7ms | ActiveRecord: 0.4ms)

You have setup a validation on terms
validates_acceptance_of :terms, :allow_nil => false, :message => :terms_not_accepted, :on => :create
So, its mandatory to check the terms checkbox while creating a new User. If you don't select the checkbox then your validation fails and you get the error. And ofcourse user record doesn't get saved.
As per the server log, while submitting the form you didn't select the terms checkbox as "terms"=>"0"(in params hash).
Make sure that you select the terms before submitting the form.

Related

Rails devise could't update User model fields

I couldn't update user information following suggested procedures on devise's own page. When I click the Update button in the form it redirects back to to user/show without updating anything. The logs on console shows the RegistrationsController#update action was called instead the update_resource action from my custom RegistrationController.
logs:
Started PATCH "/users" for 127.0.0.1 at 2016-12-11 18:34:51 +0200
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"5vqLuQKyuJIoCx0mYfBUhIQmvS0Il5jy+ty1f2XDsehJM4i3M8mMPK5tdPpVQ6MFHIj05ZcRKO7rhlxroM75pQ==", "user"=>{"first_name"=>"Birhanu", "last_name"=>"Hailemariam2", "email"=>"birhanuh4#gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update User"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Account Load (0.4ms) SELECT "public"."accounts".* FROM "public"."accounts" WHERE "public"."accounts"."subdomain" = $1 LIMIT 1 [["subdomain", "test3"]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
(0.3ms) BEGIN
(0.7ms) SELECT COUNT(*) FROM "users"
(0.3ms) ROLLBACK
Redirected to http://test3.lvh.me:3000/users/1
Completed 302 Found in 120ms (ActiveRecord: 4.5ms)
Started GET "/users/1" for 127.0.0.1 at 2016-12-11 18:34:51 +0200
views/devise/registrations/edit.slim
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= f.input :first_name, autofocus: true
= f.input :last_name, autofocus: true
= f.input :email, autofocus: true
- if devise_mapping.confirmable? && resource.pending_reconfirmation?
div
|Currently waiting confirmation for: = resource.unconfirmed_email
.form-actions.col-sm-offset-3.m-b-xs
i
|(leave blank if you don't want to change it)
= f.input :password, autocomplete: "off"
= f.input :password_confirmation, autocomplete: "off"
.form-actions.col-sm-offset-3.m-b-xs
i
|(we need your current password to confirm your changes)
= f.input :current_password, autocomplete: "off"
.form-actions.form.col-sm-offset-3
=> link_to I18n.t('button.cancel'), :back, class: 'btn btn-primary btn-outline'
= f.button :submit, class: 'btn btn-primary'
controller/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, user_params)
resource.update_with_password(user_params)
end
def after_update_path_for(resource)
current_account
end
end
controllers/application_controller.rb
class ApplicationController < ActionController::Base
.
.
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:accept_invitation, keys: [:first_name, :last_name])
devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name, :email, :password, :password_confirmation,
:current_password])
end
.
.
end
routes:
devise_for :users, controllers: { registrations: 'registrations' }
I have managed to find what was causing the issue. It is because I have a private method that was returning false value to before_save ActiveRecord callback. Fact source: enter link description here
Previous version:
private
def set_admin
self.admin = User.count == 0
end
It should be changed to return nil in case of false value.
private
def set_admin
self.admin = User.count == 0
nil
end
Now everything works, I can update user info!

Act-As-Taggable not saving to database

Hi I am attempting to use act_as_taggable ruby gem and have followed the github guide and a recent tutorial as well as checked stack overflow for advice. My code all seems to be correct but when I attempt to save tags via my form partial or via the rails console they do not save to the database.
Below relevant code excerpts.
Thanks in advance for any help!
post.rb
class Post < ActiveRecord::Base
acts_as_taggable
acts_as_taggable_on :tags
validates :title, presence: true, length: {minimum: 5}
validates :body, presence: true
extend FriendlyId
friendly_id :title, use: :slugged
end
post_controller.rb
class PostsController < ApplicationController
before_action :find_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
if params[:tag].present?
#posts = Post.tagged_with(params[:tag]).paginate(:page => params[:page], :per_page => 10)
else
#posts = Post.all.order('created_at DESC').paginate(page: params[:page], per_page: 10)
end
end
def new
#post = Post.new
end
def show
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post, notice: "Article succesfully saved!"
else
render 'new', notice: "Try Again. I was unable to save your post."
end
end
def edit
end
def update
if #post.update(params[:post].permit(:title, :body))
redirect_to #post, notice: "Article succesfully edited!"
else
render 'edit'
end
end
def destroy
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :body, :slug, :tag_list => [])
end
def find_post
#post = Post.friendly.find(params[:id])
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, :skip => :registrations
root 'pages#home'
resources :posts
resources :portfolios
get 'tags/:tag', to: 'posts#index', as: :tag
end
_form.html.erb
<%= form_for #post do |f| %>
<% if #post.errors.any? %>
<div id="errors">
<h2><%= pluralize(#post.errors.count, "error") %> prevented this post from saving:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.label :title %><br>
<%= f.text_field :title, class: 'form-control form-control-lg' %><br>
<br>
<%= f.label :body %><br>
<%= f.text_area :body, class: 'form-control form-control-lg', :rows => "10" %><br>
<br>
<%= f.label :tag_list, "Tags (separated by commas)" %>
<%= f.text_field :tag_list, class: 'form-control' %>
<br>
<%= f.submit %>
<% end %>
excerpt from show.html.erb
<% #post.tags.any? %>
<% #post.tags.each do |tag| %>
<li><a href="#">
<%= link_to tag.name, tag_path(tag.name) %>
</a></li>
<% end %>
Params log for _form as requested by Pavan:
Started PATCH "/posts/my-third-post-with-tags" for ::1 at 2015-09-23 15:56:36 +1000
Processing by PostsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"GwLMImKSDyhPt77nI+fhIkF4QVsFxMen851wjcVorrxOCdU+TcRKIZv1im4/oNx7DERYCI91vE9YDjvSda7MAg==", "post"=>{"title"=>"My third post with tags", "body"=>"to update your local repository to the newest commit, execute\r\ngit pull\r\nin your working directory to fetch and merge remote changes.\r\nto merge another branch into your active branch (e.g. master), use\r\ngit merge <branch>\r\nin both cases git tries to auto-merge changes. Unfortunately, this is not always possible and results in conflicts. You are responsible to merge those conflicts manually by editing the files shown by git. After changing, you need to mark them as merged with\r\ngit add <filename>\r\nbefore merging changes, you can also preview them by using\r\ngit diff <source_branch> <target_branch>", "tag_list"=>"tag, css"}, "commit"=>"Update Post", "id"=>"my-third-post-with-tags"}
Post Load (0.1ms) SELECT "posts".* FROM "posts" WHERE "posts"."slug" = ? ORDER BY "posts"."id" ASC LIMIT 1 [["slug", "my-third-post-with-tags"]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Unpermitted parameter: tag_list
(0.0ms) begin transaction
(0.0ms) commit transaction
Redirected to http://localhost:3000/posts/my-third-post-with-tags
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)
Started GET "/posts/my-third-post-with-tags" for ::1 at 2015-09-23 15:56:36 +1000
Processing by PostsController#show as HTML
Parameters: {"id"=>"my-third-post-with-tags"}
Post Load (0.1ms) SELECT "posts".* FROM "posts" WHERE "posts"."slug" = ? ORDER BY "posts"."id" ASC LIMIT 1 [["slug", "my-third-post-with-tags"]]
ActsAsTaggableOn::Tag Exists (0.1ms) SELECT 1 AS one FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = ? AND "taggings"."taggable_type" = ? AND "taggings"."context" = ? LIMIT 1 [["taggable_id", 2], ["taggable_type", "Post"], ["context", "tags"]]
ActsAsTaggableOn::Tag Load (0.1ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = ? AND "taggings"."taggable_type" = ? AND "taggings"."context" = ? [["taggable_id", 2], ["taggable_type", "Post"], ["context", "tags"]]
Rendered posts/show.html.erb within layouts/application (3.2ms)
Rendered layouts/_header.html.erb (496.3ms)
Rendered devise/shared/_links.html.erb (0.2ms)
Rendered devise/sessions/_new.html.erb (4.6ms)
Rendered layouts/_slideoutpanels.html.erb (460.2ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 1486ms (Views: 1484.3ms | ActiveRecord: 0.2ms)
Your error is from PostsController#update as HTML
In controller you don;t permit tag_list
#post.update(params[:post].permit(:title, :body))

link to update model parameter yields missing or empty value error

I'm trying to give provide a series of links that when selected will update a corresponding user's parameter to that which is supplied by the link without rendering a form. The only problem I'm running into is that when it calls the update method I get: param is missing or the value is empty: user.
update method
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to list_path
flash[:success] = "User updated"
else
redirect_to list_path
flash[:alert] = "User not updated"
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation, :title, :role, :address, :phone)
end
link_to
<% User.all.each do |user| %>
<% if user.role == "new" %>
<tr>
<td><%= user.name %></td>
<td><%= user.title %></td>
<td><%= user.role %></td>
<td><%= link_to "Admin", update_user_path(id: user.id, :role => "admin"), :method => :put %> / <%= link_to "Moderator", '#' %> / <%= link_to "Member", '#' %> / <%= link_to "Other", '#' %></td>
</tr>
<% end %>
<% end %>
param.inspect
{"_method"=>"put",
"authenticity_token"=>"AUcV1swtGmRuDelTzLkbLd9Gmj6+phnHaSFRqrvDyETLoxNUQSaAgkes4ViWXoAZ33K5NZojVz9XdgIIsqJblA==",
"id"=>"2",
"role"=>"admin"}
From what I've found the params.inspect should have something like [:user] => before all the parameters listed, but I cannot figure out why it is not nor can I successfully find a way to clarify.
error:
param is missing or the value is empty: user
def user_params
**params.require(:user).permit(:name, :email, :password,**
:password_confirmation, :title, :role, :address, :phone)
end
end
Log after link select
Started PUT "/update_user?id=4&role=admin" for 97.78.175.155 at 2015-06-30 15:51:47 +0000
Cannot render console from 97.78.175.155! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by UsersController#update as HTML
Parameters: {"authenticity_token"=>"m+LcLOBL5NBXHQXD19o45/iV07/V1HiAXpykV+NiXIpRBtqubUB+Nn68DciNPaPT+KHwtPFRNnhgy/f16gPPWg==", "id"=>"4", "role"=>"admin"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 4]]
Unpermitted parameters: _method, authenticity_token, id
(0.2ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('qwerty#poster.com') AND "users"."id" != 4) LIMIT 1
(0.1ms) rollback transaction
Redirected to https://rails-tutorial-hougthonbrad.c9.io/list
Completed 302 Found in 11ms (ActiveRecord: 0.7ms)
Started GET "/list" for 97.78.175.155 at 2015-06-30 15:51:47 +0000
Cannot render console from 97.78.175.155! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by UsersController#list as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
User Load (0.5ms) SELECT "users".* FROM "users"
Rendered users/list.html.erb within layouts/application (3.4ms)
Completed 200 OK in 172ms (Views: 165.1ms | ActiveRecord: 0.7ms)
Change your update action to the below.
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to list_path
flash[:success] = "User updated"
else
redirect_to list_path
flash[:alert] = "User not updated"
end
end
Update #1:
Looking at your params, you need to change your user_params like the below.
def user_params
params.require(:user).permit(:id, :name, :email, :password, :password_confirmation, :title, :role, :address, :phone)
end
Update #2:
Try changing your link_to to the below
<%= link_to "Admin", update_user_path(user, user: {:id => user.id, :role => "admin"}), :method => :put %>
You have params.require(:user) within your user_params.
That user hash is usually generated by form_for.
I would suggest to render a form with all fields hidden except the submit button for your use case.

Getting "Unpermitted parameters" error for deivse

Hi am working on sample app where I am using devise for authentication.
I am adding following extra parameters while registration.
:first_name, :last_name, :mobile, :gender, :address
But I am getting following Unpermitted parameters: first_name, last_name, password_confirmation error while registering new user.
I refereed following links
Add Custom Field/Column to Devise with Rails 4
http://www.jacopretorius.net/2014/03/adding-custom-fields-to-your-devise-user-model-in-rails-4.html
But it didn't worked. Here is not code set
user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates_confirmation_of :password, :only => :create
end
I also implemented same in application controller but it didn't worked so I created separate
registration controller.
registration_controller.rb
class RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name, :mobile, :gender, :address, :email, :password, :password_confirmation)
end
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:name,
:email, :password, :password_confirmation, :current_password)
end
end
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
private
def after_sign_in_path_for(resource)
user_landing_page
end
def user_landing_page
contact_us_path
end
end
devise/registration/new.html.haml
.container
.row
.col-sm-6.col-md-4.col-md-offset-4
%h1.text-center.login-title Create New Account
.account-wall
%img.profile-img{:alt => "", :src => "https://lh5.googleusercontent.com/-b0-k99FZlyE/AAAAAAAAAAI/AAAAAAAAAAA/eu7opA4byxI/photo.jpg?sz=120"}
= form_for(resource, as: resource_name, class: "form-signin input-medium", url: session_path(resource_name)) do |f|
= f.text_field :first_name, class: "form-control", placeholder: "First Name", autofocus: true
= f.text_field :last_name, class: "form-control", placeholder: "Last Name", autofocus: true
= f.email_field :email, class: "form-control", placeholder: "Email", autofocus: true
= f.password_field :password, class: "form-control", placeholder: "Password", autocomplete: "off"
= f.password_field :password_confirmation, class: "form-control", placeholder: "Confirm Password", autocomplete: "off"
= f.submit "Log in", class: "btn btn-lg btn-primary btn-block login-button"
development.log
Parameters: {"utf8"=>"✓", "authenticity_token"=>"pe7wBW3iWnn39p3nJAi8utbuECj+x8zX/pIxr/6sKbo=", "user"=>{"first_name"=>"first_name", "last_name"=>"last_name", "email"=>"admin#my.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Log in"}
Unpermitted parameters: first_name, last_name, password_confirmation
Rendered devise/sessions/new.html.haml within layouts/application (6.6ms)
Rendered layouts/_home_header.html.haml (1.2ms)
Completed 200 OK in 426ms (Views: 316.8ms | ActiveRecord: 0.0ms)
routes.rb
Rails.application.routes.draw do
root :to => 'landing#index'
devise_for :users, :controllers => {:registrations => "registrations"}
get '/about_us' => 'statics#about_us', as: :about_us
get '/contact_us' => 'statics#contact_us', as: :contact_us
end
can any one suggest what I am missing.
I am using Rails 4.1.4, ruby 2.1.2 and devise 3.4.1.
As per my understanding, you are registering new user. Here is your mistake
= form_for(resource, as: resource_name, class: "form-signin input-medium", url: session_path(resource_name)) do |f|
you are using session_path that means you are going to "Log In" not for "Sign Up". So change it
= form_for(resource, as: resource_name, class: "form-signin input-medium", url: registration_path(resource_name)) do |f|

Strong Params won't save nested has_many

I'm using Rails 4, and with it Strong Params. For some reason I can't save my nested parameters. I've looked at how to do it and even might've gotten it working in a different Rails app before. I know to permit draft_players_attributes and list all of it's accepted params in an array.
Here are the params coming in:
Started POST "/draft_groups" for 127.0.0.1 at 2013-12-04 22:55:32 -0500
User Load (1.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Processing by DraftGroupsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"2W3bs1U7+CEzsWl+jDi3xZi5CyldYeZXCz3KU6c+sYY=", "draft_group"=>{"name"=>"Best Group Ever", "draft_id"=>"3", "captain_id"=>"1"}, "draft_players"=>{"player_id"=>"1", "position"=>"Handler", "rating"=>"10", "info"=>"Smart"}, "commit"=>"Update"}
(0.3ms) BEGIN
SQL (2.6ms) INSERT INTO "draft_groups" ("captain_id", "created_at", "draft_id", "name", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["captain_id", 1], ["created_at", Thu, 05 Dec 2013 03:55:32 UTC +00:00], ["draft_id", 3], ["name", "Best Group Ever"], ["updated_at", Thu, 05 Dec 2013 03:55:32 UTC +00:00]]
(0.5ms) COMMIT
Redirected to http://lvh.me:3000/drafts/3
Completed 302 Found in 8ms (ActiveRecord: 3.3ms)
Here's my controller:
class DraftGroupsController < ApplicationController
def create
#draft_group = DraftGroup.create(draft_group_params)
redirect_to :back, :notice => "Draft Group successfully created."
end
def update
#draft_group = DraftGroup.find(params[:id])
#draft_group.update(draft_group_params)
redirect_to :back, :notice => "Draft Group successfully updated."
end
def destroy
#draft_group = DraftGroup.find(params[:id]).destroy
redirect_to :back, :notice => "Draft Group successfully destroyed."
end
private
def draft_group_params
params.require(:draft_group).permit(:name,
:draft_id,
:captain_id,
draft_players_attributes:
[
:_destroy,
:id,
:player_id,
:position,
:rating,
:info
]
)
end
end
And my models:
class DraftGroup < ActiveRecord::Base
has_many :draft_players, :dependent => :destroy
belongs_to :captain, :class_name => "User"
accepts_nested_attributes_for :draft_players
end
class DraftPlayer < ActiveRecord::Base
belongs_to :draft_group
belongs_to :player, class_name: "User"
end
And my view:
<% #groups.each do |group| %>
<div class="span6 group">
<h4><%= "#{group.name}" %></h4>
<%= simple_form_for(group, :html => { :class => "auto-width" } ) do |f| %>
<div class="row">
<%= f.input :name, :label => false %>
<%= f.hidden_field :draft_id %>
<%= f.hidden_field :captain_id %>
</div>
<table>
<tr>
<th>Player</th>
<th>Position</th>
<th>Rating</th>
<th>Info</th>
</tr>
<%= simple_fields_for :draft_players do |player| %>
<tr>
<td><%= player.input :player_id, :label => false, :as => :select, :collection => User.active %></td>
<td><%= player.input :position, :label => false %></td>
<td><%= player.input :rating, :label => false %></td>
<td><%= player.input :info, :label => false %></td>
</tr>
<% end %>
</table>
<div class="row">
<%= f.button :submit, "Update", :class => "btn btn-primary" %>
</div>
<% end %>
</div>
<% end %>
EDIT: Added view code, and will probably take table out, shifting it into using bootstraps columns layout.
To make sure parameters are nested correctly (and so Rails can understand nested model attributes) you should call f.simple_fields_for(:draft_players) rather than simple_fields_for(:draft_players).
In other words, call simple_fields_for on the FormBuilder object f rather than calling the helper directly.
That way Rails can look up and validate the nested association correctly.