Hello again, stackoverflow community!
I'm working on writing a simple blog system in Rails, and I'm using Devise for the authentication part.
I got the basic email/password registration going, and now I've set up a one-to-one connection of the users table (the basic one generated by devise) and a UserData table, containing things such as username, permissions, about, and so on.
It's pretty easy - the user table is 100% devise vanilla, and has_one UserData. Userdata belongs_to a user.
I tried expanding the sign up form generated by Devise, so that it would allow a user to enter, not just his e-mail and password, but also his desired user name. That way, when the form would be sent, if the names of the form fields would be correct (the right structure of nested hashes, such as "email" for the user's email, and "UserData[name]" for the user's desired name), the new user would be created automatically, and the proper corresponding UserData entry should also be created automatically by Rails, correct?
Right now, I'm having a huge issue with the UserData[name] field not appearing at all... Here's the file I'm having trouble with...
new.html.erb
<%= 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 %></div>
#This is the tidbit that doesn't work
<%= f.fields_for "UserData" do |ud_f| %>
<%= ud_f.label "username" %>
<%= ud_f.text_field :name %>
<% end %>
<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 :partial => "devise/shared/links" %>
I have been searching for an answer for hours and hours, but to no avail. If I purposely misspell the word "UserData" in the fields_for block, it prints out the field. This is strange, and I have no idea what's making that field disappear...
I'd really appreciate a little bit of help! Thanks for your time! :)
edit 1+2:
After a few messing around, I've overridden devise's default registration controller and created my own. I've edited the devise route to call my custom controller as timbrandes suggested, but I can't seem to access @user in my controller. Here's the code I have so far...
class RegistrationsController < Devise::RegistrationsController
def new
resource = build_resource({})
resource.UserData = UserData.new
respond_with resource
end
def create
logger.debug "\n\n\nIN CREATE\n\n\n\n"
logger.debug params.to_json
super
end
def update
super
end
end
Well, a lot of time has passed, but I eventually got it working by scrapping and re-doing most of my Devise code. To be honest, it wasn't that much to re-write, and now it works great.
For any future developers browsing this (slightly confusing) question and answer, the only advice I can give you is to make sure to write structured form code, especially for nested resources. This is my current
registrations_controller.rb
that works:And the .erb for the registration form:
There is a reason your fields don't appear, that is, you have to call (for example)
@user.user_data.build
somewhere in your Controller (RC #196 Nested Model Form Part 1) to make an instance of the user_data object that relates to the fields_for fields.Own way I can think of is to go with a custom devise controller (see list of Controllers), pick the corresponding method for registration and add something like
@user.user_data.build
to it.The other way is to denormalize your data scheme and put everything into User itself (not really an answer to your question but anyway ;-)). Plus: no messing with monkey patched Devise Controllers.
Make sure that you have defined accepts_nested_attributes_for :user_data in your devise model.