I have looked at other answers on here and have yet to find one. I am creating a Rails 4 app that allows users to sign in and create a profile. I am using Devise gem for user authentication.
What I want to do is have the user also type in their name and a description of themselves during the signup process. When submit the form the database will be updated with this info as well. Here is what I have done:
1) I ran a migration to create the new columns, "name" and "description", in the users table
2) I ran rails generate devise:views. This allows me to access devise>views>registrations>new.html.erb where I included the "name" label and field. I just used the other labels and fields as a guide. I now get an error saying name_field method is undefined. Where are the other ones like email_field and password_field defined?
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :name %><br />
<%= f.name_field :name %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
Any help in getting this working I would greatly appreciate.
There's no method on the Rails form object that says name_field. name_field is not a valid HTML form input type. Did you do find and replace? You should change
<%= f.name_field :name %>
to
<%= f.text_field :name %>
UPDATE
Overriding configure_permitted_parameters in app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, rest_of_user_attrs) }
# you control which attributes can be updated or used for sign in here
end
end
Here's more information for your perusal https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address
#user2623706 have you configured devise for strong parameters. That may be the problem.
Related
I am working on a rails application (ruby 3 and rails 7). I have two models. One is User(which comes by devise gem) and the other one is Role. User belongs to role and role has many users. What I am trying to do is when a new user is signing up, he/she should be by default developer.
The one way through which I solved this is by writing default value in the migration file of users but that approach is prohibited by my supervisor. Is there any other way. I dont want to use rolify or any other gems for roles and I have separate table for roles.
Roles: Admin, Developer
I did it. I create some fields when name, bio... When using gem devise
Gem devise https://www.rubydoc.info/github/plataformatec/devise/Devise/ParameterSanitizer
In devise/registrations/new.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
// Hidden role_id. EX: role_id is 1 as Developer
<%= f.hidden_field :role_id, autofocus: true, value: "1", autocomplete: "name" %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</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: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:role_id])
devise_parameter_sanitizer.permit(:account_update, keys: [:website, :bio])
end
end
I'm trying add a username field to my register using devise
views/devise/registrations/new/html.erb
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username, autofocus: true, autocomplete: "email" %>
</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: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
I got an error: "undefined method `username' for #Usermanagement:0x00007f3db801a8e0"
What did I do wrong? I'm new with ROR so please help me to figure out. Thank you!
in addition to the comment from #hazg, you might find the below link from the devise wiki helpful.
This is a walkthrough on how to add the username to your devise model:
https://github.com/heartcombo/devise/wiki/How-To:-Allow-users-to-sign-in-with-something-other-than-their-email-address
Assuming that you have named your Devise Model a User
Add username field to Devise User Model
$ rails generate migration add_username_to_users name:string
Migration file should look like this
class AddUsernameToUsers < ActiveRecord::Migration
def change
add_column :users, :username, :string
end
end
Migrate the Database
$ rails db:migrate
Generate Devise views
$ rails generate devise:views -v registrations
Update sign up & edit profile form
# views/devise/registrations/new.html.erb
# views/devise/registrations/edit.html.erb
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username, autofocus: true %>
</div>
Override the devise 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_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :email, :password])
devise_parameter_sanitizer.permit(:account_update, keys: [:username, :email, :password, :current_password])
end
end
Add model validations
class User < ApplicationRecord
validates_presence_of :username
# ...
end
I'm currently running the following:
Rails 4.0.2
Devise 3.2.2
From the Devise documentation it states that Strong Parameters will block all but the following attributes by default - email, password, password_confirmation, current_password.
I edited the new.html.erb in my registration Devise Views to contain three additional attributes - first_name, last_name, profile_name as shown below.
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :first_name %><br />
<%= f.text_field :first_name %></div>
<div><%= f.label :last_name %><br />
<%= f.text_field :last_name %></div>
<div><%= f.label :profile_name %><br />
<%= f.text_field :profile_name %></div>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
For some reason a user can still register by inputting information in all the fields, even the new fields that I added. Is there a reason my attributes are all being allowed by default?
I'm new to programming and I'm following my first rails tutorial so I'm sure I'm making a completely obvious mistake but I can't figure it out and haven't been able to find the same problem by searching online.
Thank you
Gemfile
gem "strong_parameters"
config/application.rb
config.active_record.whitelist_attributes = false
aplication_controller
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :first_name
end
With strong parameters there is no implicit validation on the client side as to whether or not the fields are allowed, but these fields will not actually be saved to the database until you explicitly permit them in your controller. You should be able to verify that the controller is blocking those fields by watching your server console during the create/update action.
The user could enter, but it's not permitted for mass assignment. The following are from Devise README:
In case you want to permit additional parameters (the lazy way™) you can do with a simple before filter in your ApplicationController:
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end
Read more about this on Devise's README, strong parameter section.
To start off, I'm new to rails, so I'm still getting the hang of things.
I'm attempting to add two fields to the Devise sign up page, a first name field and a last name field. I've gone ahead and changed the view and the controller in order to attempt this. They look like this:
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_devise_permitted_parameters, if: :devise_controller?
protected
def configure_devise_permitted_parameters
registration_params = [:firstName, :lastName, :email, :password, :password_confirmation]
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
View:
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :firstName %><br />
<%= f.fName_field :firstName %></div>
<div><%= f.label :lastName %><br />
<%= f.lName_field :lastName %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
However, I get this error when I go to view the page:
undefined method `fName_field' for #<ActionView::Helpers::FormBuilder:0x00000003c89940>
Where must I define those methods? or are they automatically defined somewhere else?
Thanks for any help.
With "f.something" you can just define the type of the field in the form. Try something like
<%= f.text_field :lastName %>
This should work.
You can read about the available types of fields here: http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for
create a migration like this to add first name and last name to users table:-
class AddFirstnameAndLastnameToUsers < ActiveRecord::Migration
def change
add_column :users, :firstName, :string
add_column :users, :lastName, :string
end
end
And add this to your view :-
<div><%= f.label :firstName %><br />
<%= f.text_field :firstName%></div>
<div><%= f.label :lastName %><br />
<%= f.text_field :lastName %></div>
You can not do f. to column of the table, you do it on the type of the field.
undefined method `fName_field'
This means you don't have the fName column in your database
If you have access to your DB, you'll see that Devise produces a table with a bunch of columns inside. By default, these columns only include email & password for the user. To add more, you first need to add the column to the database & then you should be able to do what you're doing with it.
There's a good railscast on devise you can see how to do this
I know it's a very common mistake done by a rookie while creating a registration form on the very first time because the devise puts all of the fields like f.email_field,f.password_field etc but these all are valid controls, so the developer gets confuse to type an attribute with _field
The 'fname_field' you used to define your first name is not acceptable as the form controls.
Please verify all of the controls which can be used here
and as per the current scenario, you should go for f.text_field
I am using the Devise authentication gem for a Ruby on Rails app. When a user logs in by creating a new session I would like to update a column in my user model. What would be the best way to do this?
Is there any way to have a hidden field that updates the model?
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<% if devise_mapping.rememberable? -%>
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
<% end -%>
<% f.hidden_field :field_a, :value => 'test' %>
<div><%= f.submit "Sign in" %></div>
<% end %>
You can do this by overwriting Devise::SessionsController create method. When the user login it will just authenticate the user, it wont update user record. So there is no use of keeping the hidden field in the form
Try like this
class Users::SessionsController < Devise::SessionsController
def create
#do your update here
end
end
or else you can follow this link http://denmarkin.tumblr.com/post/5194645960/how-to-overwrite-devise-sessions-controller-in-rails-3