I am getting this error message when I try to load my sign up page with devise. I have a name input in my migrate file, so I am not sure where the no method error is coming from.
Error:
NoMethodError in Devise::Registrations#new
Showing /Users/ericpark/rails_projects/bloccit-2/app/views/devise/registrations/new.html.erb where line #9 raised:
undefined method `name' for #
For page new.html.erb
<h2>Sign up</h2>
<div class="row">
<div class="col-md-8">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, autofocus: true, class: 'form-control', placeholder: "Enter name" %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control', placeholder: "Enter email" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control', placeholder: "Enter password" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control', placeholder: "Enter password confirmation" %>
</div>
<div class="form-group">
<%= f.submit "Sign up", class: 'btn btn-success' %>
</div>
<div class="form-group">
<%= render "devise/shared/links" %>
</div>
<% end %>
</div>
</div>
Application Controller:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :name
end
end
Migrate File for Users:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :name #Added by Bloc.io
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
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
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
For some reason, that part of your migration is being ignored. So lets build a new migration to add name to the users table.
In console, run:
rails g migration addNameToUsers name:string
then run
rake db:migrate
Are you able to create users with names from the rails console? If you can't you probably need to reset your database (rake db:reset).
Related
My application controller file
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) {|u| u.permit(:username, :email, :password, :password_confirmation, :remember_me)}
devise_parameter_sanitizer.permit(:sign_in) {|u| u.permit(:username, :email, :password, :password_confirmation, :remember_me)}
devise_parameter_sanitizer.permit(:account_update) {|u| u.permit(:email, :password, :password_confirmation, :remember_me)}
end
end
My routes.rb file
Rails.application.routes.draw do
devise_for :users
root 'pages#index'
get 'home' => 'pages#home'
get 'profile' => 'pages#profile'
get 'explore' => 'pages#explore'
end
My migration files
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
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
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
My add username column migration
class AddUsernameToUsers < ActiveRecord::Migration
def change
add_column :users, :username, :string
add_index :users, :username, unique: true
end
end
My views/devise/registrations/new.html.erb
<%= bootstrap_devise_error_messages! %>
<div class="panel panel-default devise-bs">
<div class="panel-heading">
<h4><%= t('.sign_up', default: 'Sign up') %></h4>
</div>
<div class="panel-body">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { role: 'form' }) do |f| %>
<div class="form-group">
<%= f.label :username %>
<%= f.text_field :email, autofocus: true, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
</div>
<%= f.submit t('.sign_up', default: 'Sign up'), class: 'btn btn-primary' %>
<% end %>
</div>
</div>
<%= render 'devise/shared/links' %>
So even after using strong parameters when the usernames being added through browser are not reflected back in the database.
It gives this result
irb(main):001:0> u = User.all
User Load (20.0ms) SELECT "users".* FROM "users"
=> #<ActiveRecord::Relation [#<User id: 1, email: "testuser#test.com", created_at: "2017-07-05 19:42:19", updated_at: "2017-07-05 21:11:38", username: nil>, #<User id: 2, email: "ajha#test.com", created_at: "2017-07-06 08:45:18", updated_at: "2017-07-06 08:45:18", username: nil>, #<User id: 3, email: "akasd#test.com", created_at: "2017-07-06 08:56:15", updated_at: "2017-07-06 08:56:15", username: nil>, #<User id: 4, email: "rcontest#test.com", created_at: "2017-07-06 09:23:55", updated_at: "2017-07-06 09:23:55", username: nil>]>
Any help will be appreciated. Also tell me if you need to see any other files.
My devise User model custom field username always nil
Because you don't have it in the form. Change
<div class="form-group">
<%= f.label :username %>
<%= f.text_field :email, autofocus: true, class: 'form-control' %>
</div>
to this
<div class="form-group">
<%= f.label :username %>
<%= f.text_field :username, autofocus: true, class: 'form-control' %>
</div>
you did not specify username attribute in the form
add username in the form
<div class="form-group">
<%= f.label :username %>
<%= f.text_field :username, autofocus: true, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
</div>
I want to add an input to my Devise user sign_up form in order to add a team name. I created a specific table for Teams and I created a relationship: Users belong to Team. Team has many users.
The problem is I need to add a Team_id when submiting the sign_up form. How can I save the value of the Team input in the register form to the Team table and get the Id in order to save it to the team_id entry in Devise User table?
My Sign Up form:
<div class="container_index">
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.label :team %><br />
<%= f.text_field :team %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
My user schema:
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.integer "team_id"
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
t.index ["team_id"], name: "index_users_on_team_id"
end
My application controller:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
skip_before_action :verify_authenticity_token
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:name, :email, :password, :team) }
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:name, :email, :password, :current_password, :team) }
end
Thank you.
I'm developing an application using devise , which has more than one type of user and each type has different data fields . For this, I am trying to use the idea applied here: http://blog.jeffsaracco.com/ruby-on-rails-polymorphic-user-model-with-devise-authentication.
My situation is exactly like this blog. I want to have only a login screen, but having more than one user table ( one for each type ), not to get a table with several empty fields.
The problem is that I tried to implement exactly the same as example and in my case is not working.
My models:
class User < ActiveRecord::Base
belongs_to :type, :polymorphic => true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
class Patient < ActiveRecord::Base
has_one :user, :as => :type
end
i'll put just this two models, because the others its the same for a while.
Controllers:
class PatientsController < ApplicationController
def create
#user = User.new(params[:user])
#patient = Patient.new(patient_params)
#user.type = #patient
if #patient.save
#user.save
redirect_to #patient
else
render 'new'
end
end
My view:
<%= form_for #patient, :url => patients_path(#patient), :html => {:method => :post} do |f| %>
<%= f.label :name, "Nome" %><br>
<%= f.text_field :name, placeholder:"Digite o nome do Paciente", required:"", autofocus: true %>
<br>
<%= f.fields_for :user do |u| %>
<%= u.label :email %><br />
<%= u.email_field :email %>
<%= u.label :password %>
<%= u.password_field :password, autocomplete: "off" %>
<%= u.label :password_confirmation %><br />
<%= u.password_field :password_confirmation, autocomplete: "off" %>
<% end %>
<%= f.submit "Ok" %>
<% end %>
My migrations:
class CreatePatients < ActiveRecord::Migration
def change
create_table :patients do |t|
t.string :name
t.timestamps null: false
end
end
end
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
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
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
end
end
And the error i'm getting is:
ActiveModel::MissingAttributeError in PatientsController#create can't
write unknown attribute type_id
I'm sorry for this huge post, but I did not want my doubt stay confused because I am researching this for some time and have found many related things , but nothing that would solve the problem.
Thanks for reading.
I know this question has been asked number of times so far and I have tried figured out my solution from them but none of them worked for me.
Since I am learning rails and newbie in this open source world so its very hard for me to get this done.
Problem is: I have user form on which I have implemented the profile form as well. so when user hits sign up, email and password goes to user table while rest of the data goes to profile table with user id in it.
Here is the code for my user model:
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_one :profile
accepts_nested_attributes_for :profile
end
here is the code of profile model:
class Profile < ActiveRecord::Base
belongs_to :user
end
this is my registration controller:
class Users::RegistrationsController < Devise::RegistrationsController
def new
#user = User.new
user.build_profile
end
def create
#user = User.new(user_params)
if #user.save
flash[:success] = "User Created"
redirect_to dashboard_index
end
end
def user_params
params.require(:user).permit(
:email,
:password,
profile_attributes: [
[:user_id => current_user.id],
:full_name,
:secondary_email,
:zip_code]
)
end
end
here is my html form with nested form implemented:
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => user_registration_path) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<% f.fields_for :profile do |p| %>
<div class="field">
<%= p.label :full_name %><br />
<%= p.text_field :full_name, autocomplete: "off" %>
</div>
<div class="field">
<%= p.label :secondary_email %><br />
<%= p.text_field :secondary_email, autocomplete: true %>
</div>
<div class="field">
<%= p.label :zip_code %><br />
<%= p.text_field :zip_code, autocomplete: "off" %>
</div>
<% end %>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
Now, half data goes into the table but profile is not entering into the table of profile.
p.s I have overridden default behavior of devise gem too.
EDIT
here are the migration files for user and profile tables:
user:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.inet :current_sign_in_ip
t.inet :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
profile:
class Profile < ActiveRecord::Migration
def change
create_table(:profile) do |f|
f.integer :user_id
f.string :full_name
f.string :secondary_email
f.string :site_url
end
end
end
Some notable errors:
user.build_profile in your new action should be #user.build_profile and your user_params should look like this
def user_params
params.require(:user).permit(:email, :password, profile_attributes: [:user_id,:full_name,:secondary_email,:zip_code])
end
And you can add a hidden_field in your form to save user_id to profiles table.
<%= p.hidden_field :user_id, :value => current_user.id %>
I have this error in heroku logs:
Maybe this is because I have added name, surname and phone fields at registration? Locally my project is working fine, without problems.
User model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :surname, :phone
end
Devise registration form:
<div id="content">
<h1 class="title">Reģistrēt jaunu profilu.</h1>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="virslauks">
<span class="text2">
<%= f.label :name, "Vārds:" %><br />
<%= f.text_field :name %><br />
<%= f.label :surname, "Uzvārds:" %><br />
<%= f.text_field :surname %><br />
</span>
</div>
<div class="virslauks">
<span class="text2">
<%= f.label :phone, "Telefona Nr.:" %><br />
<%= f.phone_field :phone %>
</span>
</div>
<div class="virslauks">
<span class="text2">
<%= f.label :email, "E-pasts:" %><br />
<%= f.email_field :email %>
</span>
</div>
<div class="virslauks">
<span class="text2">
<%= f.label :password, "Parole:" %><br />
<%= f.password_field :password %><br />
<%= f.label :password_confirmation, "Vēlreiz parole:" %><br />
<%= f.password_field :password_confirmation %>
</span>
</div>
<%= f.submit "Reģistrēties" %>
<% end %>
devise_create_users:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## User details
t.string :name, :null => false, :default => ""
t.string :surname, :null => false, :default => ""
t.integer :phone, :null => false, :default => ""
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Encryptable
# t.string :password_salt
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
end
PROBLEM SOLVED:
I have solved the problem. I simply added
add_index :users, :name, :surname, :phone
in devise_create_users
Is name a column in your database? Note, it is not there by default with devise. If so, did you run rake db:migrate?