I am using Devise for authentication in a Rails 3 app. I added first_name and last_name columns to the database via db:migrate. The registration form was modified like so:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<p><%= f.label :first_name %><br />
<%= f.text_field :first_name %></p>
<p><%= f.label :last_name %><br />
<%= f.text_field :last_name %></p>
<p><%= f.label :email %><br />
<%= f.text_field :email %></p>
<p><%= f.label :password %><br />
<%= f.password_field :password %></p>
<p><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></p>
<p><%= f.submit "Sign up" %></p>
<% end %>
Validation in the User model:
validates :first_name, :last_name, :email, :password, :password_confirmation, :presence => true
For some reason I am getting "First name can't be blank" and "Last name can't be blank" validation errors. It is interesting to note that these are the two fields added in addition to the stock Devise fields. Does Devise prevent adding other fields to the User model? What other reason could there be?
Thanks.
Probably your user model has defined attr_accessible. if this is true then you have to add :first_name and :last_name to the list.
Related
rails g devise:views command generated that view
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :username %><br />
<%= f.text_field :username, :autofocus => true %></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" %>
My question is how does it work " form_for(resource, : as=>resource_name, ..."
resource is simple a record (or object) - with respect to Devise, it's usually something called User or similar. The rest of the parameters for form_for are options, detailed in the form_for docs.
I notice that both the :email and :username are calling for the email_field, which is a mistake.
I've added 2 new fields on my devise users: :first_name and :last_name
So in the registration page I've added these new fields to be filled by user.
<div>
<%= f.label :first_name %> <br>
<%= f.text_field :first_name, autofocus => true %>
</div>
<div>
<%= f.label :last_name %> <br>
<%= f.text_field :last_name %>
</div>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
Initially the autofocus was set on :email field, but now I changed to :first_name field.
The problem is when I access this page i get this error:
undefined local variable or method `autofocus' for #<#<Class:0x361ef18>:0x449d630>
What forgot I to do in my rails app?
You forgot the : before the autofocus symbol, change it to:
<%= f.text_field :first_name, :autofocus => true %>
it should be :autofocus and not autofocus
<%= f.text_field :first_name, :autofocus => true %>
The colon : is missing at the start, should be a symbol, else its treated as if local variable/assign.
When users register, I want them to be able to upload an avatar. The new registration .html.erb looks like this:
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:multipart => true} ) do |f| %>
<%= devise_error_messages! %>
<div>
<%= f.label :username %><br />
<%= f.text_field :name %>
</div>
<div>
<%= f.label :image %><br />
<%= f.file_field :image %>
</div>
<div><%= f.label :email %><br />
<%= f.email_field :email %></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 "links" %>
User.rb:
class User < ActiveRecord::Base
....
mount_uploader :image, ImageUploader
ImageUploader exists...
When I try to visit the view, it tells me that User::ImageUploader doesn't exist. When I try to specify the fully qualified name of the class in the user model, either as an 'include' statement or as an argument to the mount_uploader function, it can't find that either. Do I need to somehow build in a separate form_tag in that view? I'm sure this has been done before. Any help is appreciated.
Have you:
Added an :image column to your User model?
Defined the uploader app/uploaders/image_uploader.rb?
Restarted your server?
You shouldn't need to have this as a separate form tag, as long as the image attribute exists on the User model.
You may need to check your form markup. I notice you have :username on the label and :name on the field.
Try changing:
<%= f.label :username %><br />
<%= f.text_field :name %>
to
<%= f.label :name, "username" %><br />
<%= f.text_field :name %>
When I go to the edit_user_registration_path provided by Devise I have fields such as email and username pre-filled.
I want to create custom user profile page with the similar form for edit user information containing additional fields of dependent model. And I want fields be pre-filled.
How should I do it properly?
The default form provided by Devise:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :username %><br />
<%= f.text_field :username %></div>
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, :autocomplete => "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></div>
<div><%= f.submit "Update" %></div>
<% end %>
Use nested attributes
In your devise user model, if you have other dependent models, you can add a relationship between those models, like has_many and belongs_to. The do this:
Devise user model:
accepts_nested_attributes_for :name_of_other_model
Then in your form you can use fields_for. fields_for docs
Here's also a great railscast of this here
I just added a new column to my database. The migration didn't throw any errors and the database looks like it took the migration just fine also. I have a form, as such;
<h1>Sign up as a new user</h1>
<% #user.password = #user.password_confirmation = nil %>
<%= error_messages_for :user %>
<% form_for(#user) do |f| -%>
<p><%= f.label :login %><br/>
<%= f.text_field :login %></p>
<p><%= f.fullname :fullname %><br/>
<%= f.text_field :fullname %></p>
<p><%= f.label :email %><br/>
<%= f.text_field :email %></p>
<p><%= f.label :password %><br/>
<%= f.password_field :password %></p>
<p><%= f.label :password_confirmation, 'Confirm Password' %><br/>
<%= f.password_field :password_confirmation %></p>
<p><%= submit_tag 'Sign up' %></p>
<% end -%>
The field f.fullname was the new column I added. When I try to load up the page though, it keeps throwing an error;
undefined method `fullname' for #<ActionView::Helpers::FormBuilder:0xb6fa73e4>
I have this in my user.rb model
attr_accessible :login, :email, :fullname, :password, :password_confirmation
Am I missing something here as to why Rails keeps throwing that error?
Thanks.
It looks like the error is coming from a typo in your view:
<p><%= f.fullname :fullname %><br/>
<%= f.text_field :fullname %></p>
f.fullname should be f.label.
A clue would be that the error is coming from FormBuilder and not an ActiveRecord derivative.