Devise error: Unpermitted parameters - ruby-on-rails

How to register a user with username devise?
What I have so far throws me the following error:
Error:
Processing by Devise::SessionsController#new as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"oa1sf2dgKU/VpgOAI5ocnM8e5gNkuswxX9KKpTLFUZmUwtO40CFoseZiYQ3eQZ71bTw9R3aFOhpbD5EZcAVcGA==", "user"=>{"username"=>"MCarpintini", "email"=>"carpintinimatias#gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Register"}
Unpermitted parameters: :username, :password_confirmation
Registration form
.ui.middle.aligned.center.aligned.grid
.column
=form_for(resource, html: {class:"ui large form"}, as: resource_name,url: session_path(resource_name)) do |f|
.ui.stacked.segment
.field
.ui.left.icon.input
%i{class:"user icon"}
=f.text_field :username, placeholder: "Username"
.field
.ui.left.icon.input
%i{class:"mail icon"}
=f.email_field :email, placeholder:"Email"
.field
.ui.left.icon.input
%i{class:"lock icon"}
=f.password_field :password, placeholder:"Password"
.field
.ui.left.icon.input
%i{class:"repeat icon"}
=f.password_field :password_confirmation, placeholder:"Password Confirmation"
=f.submit "Register", class:"ui fluid large teal submit button"
.ui.error.message
.ui.message
Do you have account?
=link_to "Login", new_user_session_path
User model
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
User table structure.
create_table "users", force: :cascade do |t|
t.string "username", default: "", null: false
t.string "avatar_file_name", default: "", null: false
t.string "avatar_content_type", default: "", null: false
t.integer "avatar_file_size", null: false
t.datetime "avatar_updated_at", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

You need to permit additional parameters via strong parameters. Since you have custom parameter username defined, you would have to permit the same:
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :password_confirmation])
end

You are trying to Register a user with the wrong url. There's a problem with this line:
=form_for(resource, html: {class:"ui large form"}, as: resource_name,url: session_path(resource_name)) do |f|
url: session_path(resource_name) sends the data to SessionsController. It should be directed to the RegistrationsController.
Try replacing the form submission url to registration_path or new_registration_path or new_user_registration_path, whichever is defined in your _links.html.erb file

Related

How do I display male or female based on certain conditions in Rails?

I am new to rails and currently working on a dating application as a portfolio project. However, on my home page, I want to be able to display/render Male or Female data based on the gender of the current_user. That is if the logged-in user is a male, he will only be able to view people of the opposite gender since it's a dating application.
I am using Devise gem and included a custom field called gender. Please, someone should help me with how to do this.
class UsersController < ApplicationController
def index
#user = current_user
#users = User.all
end
def show
#user = User.find(params[:id])
end
User Table
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.text "short_bio"
t.string "gender"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.integer "like"
t.string "image_url"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
User Model
class User < ApplicationRecord
has_one_attached :image
has_many_attached :pictures
has_many :messages
has_many :likes
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :validatable, :trackable
# validates :short_bio, presence: true, length: {maximum: 500}
validates :email, presence: true, uniqueness: { case_sensitive: false }, length: {minimum: 5, maximum: 50}
end
You can only load users with the opposite gender than the current user like this:
#users = User.where.not(gender: current_user.gender)
Probably you need in the model two columns. It is just example as idea
You can use gender (it's not binary) instead of sex
You can use other data type of course
t.integer :sex
t.integer :look_for_sex
And for example:
0 -- female, 1 -- male
And then
User.where(sex: current_user.look_for_sex, look_for_sex: current_user.sex)
will return only users that current user want to date
Thank you for all that responded. I didn't have to refactor my code but just added the code below and that fixed my problem:
#users = current_user == 'Male' ? User.where(gender: 'Male') : User.where(gender: 'Female')
In this case, if the current user is a 'Male', he will only have access to 'Female' and vice versa.

ActiveRecord::StatementInvalid in Devise::RegistrationsController#create

I'm trying to add some extra information to my Devise User model like first_name, last_name, age, gender and city.
When I fill the signup form and click to submit I get this error:
SQLite3::ConstraintException: NOT NULL constraint failed: users.first_name: INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES (?, ?, ?, ?)
def each
loop do
val = step
break self if done?
yield val
end
And these are the parameters if they are any use:
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"2e5oUwMw84HtwSuI09X1O5kjPLYk7SW4VKgGOOxcB93W7sSQYjPgq3N/BGo0+oAEifhec4lQ3PUt9vub17vs7g==",
"user"=>
{"first_name"=>"Test", "last_name"=>"Test", "age"=>"69", "city"=>"New York", "gender"=>"Trans", "email"=>"test.test#email.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"},
"commit"=>"Sign up"}
Here is my schema.rb just in case:
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.string "first_name", null: false
t.string "last_name", null: false
t.integer "age", null: false
t.string "city", null: false
t.string "gender", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
Here is my user.rb model too:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
To have additional columns on user not already set in devise I allowed access in my ApplicationContoller this way. Rails4
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
# Only add some parameters
devise_parameter_sanitizer.for(:accept_invitation).concat [:first_name, :last_name]
end
or
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :full_name
end
and this would allow you to have first_name last_name with the other things that you have set up.
Rails5
def configure_permitted_parameters
additional_params = [:name, :company, :email_confirmation, {addresses_attributes: [:address1, :address2, :city, :state, :zip, :country, :name]}]
devise_parameter_sanitizer.permit(:sign_up, keys: additional_params)
devise_parameter_sanitizer.permit(:account_update, keys: additional_params)
end
You have a unique index on email. What the error is saying is that the email you are trying to save is not null in the database. A user already has this email. Change the email and it should work.
# to check for the user in the database
rails c
user = User.find_by_email("test.test#email.com") should bring back a user.

Nomethoderror trying to use Devise with rails

I'm following a guide on Devise and I am currently stuck with this:
`NoMethodError in TasksController#new undefined method `tasks' for nil:NilClass
Task.rb
class Task < ActiveRecord::Base
belongs_to :user
end
User.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :tasks
end
TaskController.rb
def new
#task = current_user.tasks.build
end
def create
#task = current_user.tasks.build(task_params)
end
DB - Schema.rb
create_table "tasks", force: :cascade do |t|
t.string "name"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Help is much appreciated!
Error message says: nil.tasks
It means the User class object is not created.
Try to login. Once you are logged in, the error will be resolved.

What am I doing wrong Ruby on Rails facebook login

This is my user model called "user.rb" and I want that people can sign in with their Facebook account and transfer their profile picture to my website. The problem is that it keeps saying that "user.image" in the "profile_picture" variable is undefined. Ruby stores the image with the paperclip gem.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable
validates :fullname, presence: true, length: {in: 2..50}
def self.from_omniauth(auth)
user = User.where(email: auth.info.email).first
if user
return user
else
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.fullname = auth.info.name
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.image = auth.info.image
user.password = Devise.friendly_token[0,20]
end
end
end
def profile_picture
if user.image
user.image
else
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100#" }, :default_url => "/images/:style/missing.jpg"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
end
end
In my html.erb file I call the image method with:
<%= image_tag current_user.avatar.url(:thumb) %>
I know I will have to change it to:
<%= image_tag current_user.profile_picture %>
Here is my schema.rb file:
ActiveRecord::Schema.define(version: 20150927111830) do
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "fullname"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "provider"
t.string "uid"
t.string "image"
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
user in the profile_picture method is out of scope. Whenever you declare a local variable within your method (e.g user), this will only be available inside the scope of that method.
current_user is an instance of User so if you want the image of that user you can simply call in your image_tag:
<%= image_tag(current_user.image) %>

Rails 4, Devise - Cannot update username from rails console

I am using Ruby on Rails 4 with devise for user authentication.
I have problem with creating user from console nor from edited devise registration view. I can set password and email, but i can't set username, I have to create user witouth name and then change it from dbconsole using SQL command ("UPDATE users SET..."). Then I can login with username.
My users table:
create_table "users", force: true do |t|
t.string "name", default: "", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
end
My users model:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:rememberable, :trackable, :validatable
validates_presence_of :name, :email, :password
attr_accessor :name
end
When I try
u = User.new
u.name = "test"
from rails console name stays blank.
Try to remove this line:
attr_accessor :name

Resources