views:

221

answers:

1

I am attempting to create an enrollment process similar to SO's:

  • route to an OpenID provider
  • provider returns the user's information to the UsersController (a guess)
  • UsersController creates user, then routes to the ProfilesController's new or edit action.

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:

  1. 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

  2. When the new-profile form is being rendered, it throws an error that reads: undefined method `user_profiles_path' for #

  3. 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.

A: 

I change the Edit-Profile form to:

<% form_for([@user,@profile], :url => user_profile_path(@user)) do |f| %>

and everything works as expected.

Craig