开发者

Rails3 singular route to mask :id

开发者 https://www.devze.com 2023-03-03 17:14 出处:网络
In the Rails Guides under 2.5 Singular Resources, it states 开发者_如何学编程 Sometimes, you have a resource that

In the Rails Guides under 2.5 Singular Resources, it states

开发者_如何学编程

Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like /profile to always show the profile of the currently logged in user. In this case, you can use a singular resource to map /profile (rather than /profile/:id) to the show action.

So I tried the example:

match "profile" => "users#show"

However, when I attempt to go to the profile_path, it attempts to redirect to the following, where id = :id:

/profile.id

This represents two issues:

  1. I dont want the id to be displayed at all, and thought this was a routing pattern to mask an id
  2. Using this method causes the following error. It also causes this error when I attempt to request user_path.

Error:

ActiveRecord::RecordNotFound in UsersController#show

Couldn't find User without an ID

I guess this is because the params being passed through look like this:

{"controller"=>"users", "action"=>"show", "format"=>"76"}

Am I using singular resources correctly?

My UsersController:

  def show    
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @user }
    end
  end

My routes:

  resources :users
  match "profile"  => "users#show"


First of all, if you want to use profile_url or profile_path you have to use :as like this:

match "/profile" => "users#show", :as => :profile

You can find an explanation here.

Secondly, in your controller you rely on params[:id] to find the user you are looking for. In this scenario there is no params[:id], so you have to rewrite your controller code:

def show
  if params[:id].nil? && current_user
    @user = current_user
  else
    @user = User.find(params[:id])
  end

  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => @user }
  end
end


Or

get "/profile/:id" => "users#show", :as => :profile
# or for current_user
get "/profile" => "users#show", :as => :profile

or

resource :profile, :controller => :users, :only => :show


It looks for an :id because probably you already have a resource profile in your routes file:

resoruce(s): profile

If it so, try to shift that line under your new line match "profile" => "users#show

It should acquire less priority and your new line should be read before the resource: profile is read.

Let me know if it is the problem and if you solve.


i did this in this way:

resources :users
  match "/my_profile" => "users#show", :as => :my_profile

and to make it workable i have to edit my controller code too:

def show

    current_user = User.where(:id=> "session[:current_user_id]")
    if params[:id].nil? && current_user
      @user = current_user
    else
      @user = User.find(params[:id])
    end

    respond_to do |format|
      format.html # show.html.erb`enter code here`
      format.xml  { render :xml => @user }
    end
  end

and at the end just give a link to my_profile:

<a href="/my_profile">My Profile</a>
0

精彩评论

暂无评论...
验证码 换一张
取 消