Rails 3 - Nested Resources Routing - One to One re

2020-04-16 19:08发布

问题:

Having some trouble with some nested resources routing. What I'm trying to do is link to a user's profile page for editing purposes. In my view it is written as:

<%= link_to "Edit Profile", edit_user_profile_path(current_user) %>

Which errors out with:

No route matches {:action=>"edit", :controller=>"profiles", :user_id=>#<User id: 1, email: "EDITEDOUT", hashed_password: "EDITEDOUT", created_at: "2011-01-20 18:30:44", updated_at: "2011-01-20 18:30:44">}

In my routes.rb file, it looks like so:

resources :users do
  resources :profiles, :controller => "profiles"
end  

I checked my Rake routes, and it gave me this as a valid option:

edit_user_profile GET    /users/:user_id/profiles/:id/edit(.:format)   {:action=>"edit", :controller=>"profiles"}

Which I am able to manually navigate to. For good measures, here's proof of my controller:

class ProfilesController < ApplicationController
  def edit
    @user = current_user
    @profile = current_user.profile
  end

  def update
    @user = current_user
    @profile = current_user.profile


    respond_to do |format|
      if @profile.update_attributes(params[:profile])
        format.html { redirect_to(orders_path, :notice => "Your profile has been updated.") }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @profile.errors, :status => :unprocessable_entity }
      end
    end
  end
end

Anyway, I've been having some problem tracking this down. Any pointers would help. For my DB design Profiles belong to Users in a one-to-one relationship. I'm hoping it's just something newbish I'm not noticing a new set of eyes might help.

回答1:

If you look closely at your route, you'll see that it expects both a :user_id and an :id. The latter, in this case, refers to the user profile.

In order to tell Rails that you want that particular profile, you'll have to specify both the user and the profile in your link, like this:

edit_user_profile_path(current_user, @profile)

Now, Rails will use the first argument (current_user) for the :user_id part of the route, and the second argument (@profile) for the :id.