Reputation: 26262
I am attempting to create an enrollment process similar to SO's:
For now, I'm simply trying to create the user, then route to the ProfilesController's new or edit action (not sure which I should be using).
Here's what I have thus far:
Models:
class User < ActiveRecord::Base
has_one :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
end
Routes:
map.resources :users do |user|
user.resource :profile
end
new_user_profile GET /users/:user_id/profile/new(.:format) {:controller=>"profiles", :action=>"new"}
edit_user_profile GET /users/:user_id/profile/edit(.:format) {:controller=>"profiles", :action=>"edit"}
user_profile GET /users/:user_id/profile(.:format) {:controller=>"profiles", :action=>"show"}
PUT /users/:user_id/profile(.:format) {:controller=>"profiles", :action=>"update"}
DELETE /users/:user_id/profile(.:format) {:controller=>"profiles", :action=>"destroy"}
POST /users/:user_id/profile(.:format) {:controller=>"profiles", :action=>"create"}
users GET /users(.:format) {:controller=>"users", :action=>"index"}
POST /users(.:format) {:controller=>"users", :action=>"create"}
new_user GET /users/new(.:format) {:controller=>"users", :action=>"new"}
edit_user GET /users/:id/edit(.:format) {:controller=>"users", :action=>"edit"}
user GET /users/:id(.:format) {:controller=>"users", :action=>"show"}
PUT /users/:id(.:format) {:controller=>"users", :action=>"update"}
DELETE /users/:id(.:format) {:controller=>"users", :action=>"destroy"}
Controllers:
class UsersController < ApplicationController
# generate new-user form
def new
@user = User.new
end
# process new-user-form post
def create
@user = User.new(params[:user])
if @user.save
redirect_to new_user_profile_path(@user)
...
end
end
# generate edit-user form
def edit
@user = User.find(params[:id])
end
# process edit-user-form post
def update
@user = User.find(params[:id])
respond_to do |format|
if @user.update_attributes(params[:user])
flash[:notice] = 'User was successfully updated.'
format.html { redirect_to(users_path) }
format.xml { head :ok }
...
end
end
end
class ProfilesController < ApplicationController
before_filter :get_user
def get_user
@user = User.find(params[:user_id])
end
# generate new-profile form
def new
@user.profile = Profile.new
@profile = @user.profile
end
# process new-profile-form post
def create
@user.profile = Profile.new(params[:profile])
@profile = @user.profile
respond_to do |format|
if @profile.save
flash[:notice] = 'Profile was successfully created.'
format.html { redirect_to(@profile) }
format.xml { render :xml => @profile, :status => :created, :location => @profile }
...
end
end
end
# generate edit-profile form
def edit
@profile = @user.profile
end
# generate edit-profile-form post
def update
@profile = @user.profile
respond_to do |format|
if @profile.update_attributes(params[:profile])
flash[:notice] = 'Profile was successfully updated.'
# format.html { redirect_to(@profile) }
format.html { redirect_to(user_profile(@user)) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @profile.errors, :status => :unprocessable_entity }
end
end
end
Edit-User View:
...
<% form_for(@user) do |f| %>
...
New-Profile View:
...
<% form_for([@user,@profile]) do |f| %>
..
I'm having two problems:
When saving an edit to the User model, the UsersController attempts to route to http://localhost:3000/users/1/profile.%23%3Cprofile:0x10438e3e8%3E, instead of http://localhost:3000/users/1/profile
When the new-profile form is being rendered, it throws an error that reads: undefined method `user_profiles_path' for #
Is it better to create a blank profile when the user is created (in the UsersController), then edit it OR follow the rest-ful convention of creating the profile in the ProfilesController (as I have done)?
What am I missing?
I did review Associating Two Models in Rails (user and profile), but it didn't address my needs.
Thanks for your time.
Upvotes: 4
Views: 2936
Reputation: 26262
I change the Edit-Profile form to:
<% form_for([@user,@profile], :url => user_profile_path(@user)) do |f| %>
and everything works as expected.
Upvotes: 2