I want to extend the sign up form of my devise installation. I created a Profile model and am asking myself now, how can I add specific data of the form to this model. Where
It's not very clear from your question, but I'm assuming your Devise model is User
and you created another model Profile
that belongs to user.
You'll need to create a controller for your User model with rails g controller users
.
You'll also need to generate the views for your users with rails generate devise:views
so that the user can add profile info when he's creating his account.
From there, it's just like any other model: create a user and profile instance and link the two. Then, in controllers, use current_user.profile
to access the current user's profile.
Note that if you're going to manage users this way, you'll need to remove the :registerable
module from the User
model (also read https://github.com/plataformatec/devise/wiki/How-To:-Manage-users-through-a-CRUD-interface)
To complement mbreining's answer, in Rails 4.x you'll need to use strong parameters to allow nested attributes to be stored. Create a registration controller subclass:
RegistrationsController < Devise::RegistrationsController
def sign_up_params
devise_parameter_sanitizer.sanitize(:sign_up)
params.require(:user).permit(:email, :password, profile_attributes: [:first_name, :last_name])
end
end
I recommend looking at Creating Profile for Devise users for a more recent answer to the same question and using Rails 4 + Devise
Assuming you have a User model with a has_one
Profile association, you simply need to allow nested attributes in User and modify your devise registration view.
Run the rails generate devise:views
command, then modify the devise registrations#new.html.erb
view as shown below using the fields_for
form helper to have your sign up form update your Profile model along with your User model.
<div class="register">
<h1>Sign up</h1>
<% resource.build_profile %>
<%= form_for(resource, :as => resource_name,
:url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<h2><%= f.label :email %></h2>
<p><%= f.text_field :email %></p>
<h2><%= f.label :password %></h2>
<p><%= f.password_field :password %></p>
<h2><%= f.label :password_confirmation %></h2>
<p><%= f.password_field :password_confirmation %></p>
<%= f.fields_for :profile do |profile_form| %>
<h2><%= profile_form.label :first_name %></h2>
<p><%= profile_form.text_field :first_name %></p>
<h2><%= profile_form.label :last_name %></h2>
<p><%= profile_form.text_field :last_name %></p>
<% end %>
<p><%= f.submit "Sign up" %></p>
<br/>
<%= render :partial => "devise/shared/links" %>
<% end %>
</div>
And in your User model:
class User < ActiveRecord::Base
...
attr_accessible :email, :password, :password_confirmation, :remember_me, :profile_attributes
has_one :profile
accepts_nested_attributes_for :profile
...
end
Another way in order not to put building resource in the view is to rewrite the devise controller and to be exact, the new method, all u need to do is to change it to:
def new
build_resource({})
resource.build_profile
respond_with self.resource
end