Getting "Unpermitted parameters" error for deivse - ruby-on-rails-4

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|

Related

Devise change email does not update email

I'm trying to allow users to change their email addresses which devise uses as their unique username. Even though the update gives no errors, no change is made to the email address for the user in the database.
Here are the relevant portions of code:
Form:
<%= f.fields_for :user_account, #user.user_account do |user_account| %>
<p>Edit email address for account: <%= #user.user_account.email %></p>
<div class="field">
<%= user_account.label :new_email %><br />
<%= user_account.text_field :email, autocomplete: "off", value: nil %>
</div>
<div class="field">
<%= user_account.label :password %> <i>(please confirm the password associated with this account)</i><br />
<%= user_account.password_field :current_password, autocomplete: "off" %>
</div>
<%= hidden_field_tag 'form', 'email' %>
<div class="actions">
<%= user_account.submit "Edit" %>
</div>
controller:
def update
respond_to do |format|
if params[:form] == 'email'
if #user.user_account.valid_password?(params[:user][:user_account_attributes][:current_password])
if #user.update(user_params)
format.html { redirect_to user_path(#user), :notice => 'your new email has been saved' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
else
format.html { redirect_to edit_email_path(#user), :notice => 'incorrect password (email)' }
end
else ...
the user_params method:
def user_params
params.require(:user).permit(
:first_name, :middle_initial, :last_name,
:linkedin, :website, :facebook, :video, :phone_number,
:address_1, :address_2, :city, :zip_code,
:image, :number, :years_practicing, :neighborhood, :biography, :price, :status,
user_employments_attributes: [:id, :user_id, :company, :position, :start_date, :end_date, :info, :_destroy],
user_educations_attributes: [:id, :user_id, :school, :degree_title, :start_date, :end_date, :info, :_destroy],
user_account_attributes: [:id, :user_id, :email, :password, :password_confirmation, :_destroy],
user_category_ids:[])
end
user account model:
class UserAccount < ActiveRecord::Base
# Include default devise modules. Others available are:
# , :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
belongs_to :user
end
Ok, so it turns out that the new email address was being saved as :unconfirmed_email, but this did not change any of the functionality of the linked account, since the account still had the old email stored as :email.
Thus I had to do
user.confirmed_at = nil
user.save(:validate => false)
in order for the user confirmation email to be resent and so that the login form would no longer accept the old password.
I am not sure, but I think, in your user model there should be
accepts_nested_attributes_for :user_account

Unpermitted parameter with nested attributes

I am trying to use the accepts_nested_attributes_for, but I get an unpermitted parameters: address when I try to create or update a field in the address model
I have a relationship between two models a Client which has an Address as follows
class Client < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
...
class Address < ActiveRecord::Base
belongs_to :client
The strong parameters are set up according to this http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html
as follows
def client_params
params.require(:client).permit(:name, :tel, :email, :website, :photo,
address_attributes: [:id, :line1, :line2,
:town, :country, :zip_code])
end
The update action in the controller uses client_params
def update
#client = Client.find(params[:id])
if #client.update(client_params)
...
the form uses form_for and field_for
form_for :client, url: path, method: mymethod, html: {multipart: true, role:'form'} do |f|
= f.text_field :name
...
= f.fields_for :address do |a|
= a.text_field :line1, label: 'First line'
= a.text_field :line2, label: 'Second line'
= a.text_field :town
= a.text_field :country
= a.text_field :zip_code
The client fields work fine. However, if i try to update one of the address fields the address in not updated and unpermitted parameter: address is logged.
Here are the parameters from such a request
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"Yx+ualZcCUZTriCIiCfF1SrFVUGdOnFgWApiYqKAMXU=",
"client"=> {
"name"=>"Alice",
"email"=>"",
"tel"=>"",
"website"=>"",
"address"=> {
"line1"=>"Casa 1",
"line2"=>"",
"town"=>"",
"country"=>"",
"zip_code"=>""}},
"commit"=>"Save Details",
"id"=>"16"}
My earlier answer was mostly irrelevant. Here's what I think the problem is, the nested attributes in the params require must reference plural of the model name.
Where you have address_attributes: must be plural addresses_attributes:
I think that's the problem.
def client_params
params.require(:client).permit(:name, :tel, :email, :website, :photo,
addresses_attributes: [:id, :line1, :line2,
:town, :country, :zip_code])
end
Please let me know how it goes.

Unable to save Join Table details to database in Rails 4

I've always had trouble with has_many :through relationships on join tables and am stuck again on where I'm going wrong. I think it might be in my controller as I'm still getting to grips with how it all works.
I have three models:
class Role < ActiveRecord::Base
has_many :assignments, inverse_of: :role
has_many :employees, :through => :assignments
accepts_nested_attributes_for :assignments
end
class Employee < ActiveRecord::Base
has_many :assignments, inverse_of: :employee
has_many :roles, :through => :assignments
accepts_nested_attributes_for :assignments
end
class Assignment < ActiveRecord::Base
belongs_to :employee, inverse_of: :assignment
belongs_to :role, inverse_of: :assignment
accepts_nested_attributes_for :employee
accepts_nested_attributes_for :role
end
I'd like to be able to set the pre-created role for an employee when creating or editing an employee. My New Employee form is as follows:
<%= semantic_form_for #employee do |f| %>
<%= render 'shared/error_messages' %>
<%= f.inputs do %>
<%= f.input :first_name %>
<%= f.input :last_name %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= semantic_fields_for :roles do |role| %>
<%= role.input :role, :as => :select, :collection => Role.all %>
<%= role.semantic_fields_for :assignments do |assignment| %>
<%= assignment.input :start_date, :as => :date_select %>
<%= assignment.input :end_date, :as => :date_select %>
<%= assignment.input :assignment_no %>
<%= assignment.input :assignment_id %>
<% end %>
<% end %>
<% end %>
<%= f.actions do %>
<%= f.action :submit, :as => :button %>
<%= f.action :cancel, :as => :link %>
<% end %>
<% end %>
and finally my Employee Controller is:
class EmployeesController < ApplicationController
before_action :set_employee, only: [:show, :edit, :update, :destroy]
def index
#employees = Employee.paginate(page: params[:page])
end
def show
end
def new
#employee = Employee.new
role = #employee.roles.build
end
def edit
#employee = Employee.find(params[:id])
end
def create
#employee = Employee.new(employee_params)
if #employee.save
#employee.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def update
respond_to do |format|
if #employee.update(employee_params)
flash[:success] = "Profile updated"
format.html { redirect_to #employee, notice: 'Employee was successfully updated.' }
format.json { render :show, status: :ok, location: #employee }
else
format.html { render :edit }
format.json { render json: #employee.errors, status: :unprocessable_entity }
end
end
end
def destroy
Employee.find(params[:id]).destroy
flash[:success] = "Employee deleted"
respond_to do |format|
format.html { redirect_to employees_url, notice: 'Employee was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_employee
#employee = Employee.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def employee_params
params.require(:employee).permit(:avatar, :email, :first_name, :last_name, :password, :assignments_attributes => [:employee_id, :role_id, :roles_attributes => [:id, :employee_id, :PID]])
end
end
I appreciate that this subject is always on Stackoverflow, but I can't seem to translate any of the problems into where I am. Any help would be greatly appreciated!
The console output is as follows:
Started POST "/employees" for 127.0.0.1 at 2015-05-16 18:05:34 +0200
source=rack-timeout id=d5933405c94d9c2e8bca3332564528ec timeout=60000ms service=25ms state=active
Processing by EmployeesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"TgHHELkt2zXUtS474WwGeHcmfKKw/broHxRdhlsF1P4JyGoa+03rchb6mfxbOSXKdrPgcJMeBCyIlCMHqPlQBA==", "employee"=>{"first_name"=>"John", "last_name"=>"Smith", "email"=>"john#smith.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "roles"=>{"role"=>"2", "assignments"=>{"start_date(1i)"=>"2012", "start_date(2i)"=>"7", "start_date(3i)"=>"5", "end_date(1i)"=>"2016", "end_date(2i)"=>"3", "end_date(3i)"=>"1", "assignment_no"=>"4", "assignment_id"=>"A3392822"}}, "button"=>""}
Unpermitted parameter: password_confirmation
(0.2ms) BEGIN
source=rack-timeout id=d5933405c94d9c2e8bca3332564528ec timeout=60000ms service=1113ms state=active
SQL (70.3ms) INSERT INTO "employees" ("email", "first_name", "last_name", "password_digest", "created_at", "updated_at", "activation_digest") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["email", "john#smith.com"], ["first_name", "John"], ["last_name", "Smith"], ["password_digest", "$2a$10$g3PNppheVZ8AFnnKuWg6secBdGev0NlCXjUx.RXsky03Xl9L3CubO"], ["created_at", "2015-05-16 16:05:35.422312"], ["updated_at", "2015-05-16 16:05:35.422312"], ["activation_digest", "$2a$10$L0yFuvmlJon7fWod6lHj..O7yDRaqwqTlTkJgD7Evqx.dA4pDTlBC"]]
(133.0ms) COMMIT
(I'm working on a very slow computer!)

Rails 4 Paperclip with Devise, file saving error

I'm using devise gem with paperclip to handle authentication and upload pictures. Problem is that I have used paperclip on the same model twice for storing two pictures (let's call those paperclip columns :avatar , :superbadge), my model name is User.
Now, when I choose to upload two pictures, my rails application ignores the first file that I have chosen, instead It uses second chosen file and saves it in the first paperclip column, leaving second paperclip column blank. How do I fix it?
My application controller:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_devise_permitted_parameters, if: :devise_controller?
protected
def configure_devise_permitted_parameters
registration_params = [:name, :email, :password, :password_confirmation,:avatar,:superstarbadge]
if params[:action] == "update"
devise_parameter_sanitizer.for(:account_update) {
|u| u.permit(registration_params << :current_password)
}
elsif params[:action] == "create"
devise_parameter_sanitizer.for(:sign_up) {
|u| u.permit(registration_params)
}
end
end
end
My User.rb model:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :validatable
has_attached_file :avatar, :styles => { :small => "100x100>" }
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
has_attached_file :superstarbadge, :styles => { :tiny => "100x100>" }, :default => "superbadge.jpg"
validates_attachment_content_type :superstarbadge, :content_type => /\Aimage\/.*\Z/
has_many :questions
has_many :answers
def to_s
email
end
end
My form_for for creating new user with devise gem (I'm using slim template language not erb):
h1 Sign up
= form_for(resource, as: resource_name, url: registration_path(resource_name), :html => { :multipart => true }) do |f|
= devise_error_messages!
.field
label= f.label :name
= f.text_field :name, autofocus: true
.field
label= f.label :email
= f.email_field :email, autofocus: true
.field
label= f.label :password
= f.password_field :password, autocomplete: 'off'
.field
label= f.label :password_confirmation
= f.password_field :password_confirmation, autocomplete: 'off'
.field
= f.label :avatar
= f.file_field :avatar
.field
= f.file_field :avatar
div
= f.submit "Sign up"
Both the file_field's in your form are referring to avatar field so when you submit the form the second chosen file (i.e., latest) gets saved as avatar. There is no file_field for superstarbadge so it never gets saved.
You need one file_field for avatar and other one for superstarbadge. So, your code should look like:
.field
= f.label :avatar
= f.file_field :avatar
.field
= f.file_field :superstarbadge ## This one should be superstarbadge and NOT avatar

issue with rails terms of service validation

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.