简体   繁体   中英

Why root route not working with users#show?

I tried this as my root route root 'users#show' so that the User is taken to his profile upon logging in, but instead I'm confronted with this error:

ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with 'id'= 
@user = User.find(params[:id])

When I use profile as its own tab via, <li><%= link_to "Profile", current_user %></li> this works, but I can't put root 'current_user' or I get this error:

ArgumentError
Missing :action key on routes definition, please check your routes.
root 'current_user'

Thank you for your time.

If you need to redirect him to show action and show details of current user , then set the current_user as @user :

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

Actually, the error message that you've provided points the problem.

If you have root defined as you've mentioned root "users#show" it properly executes the show action of UsersController , but if you have that action implemented "the standard way":

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

it fails here, because there is no params[:id] . The value is fetched from url. If you're pointing the url:

localhost:3000/users/1

the params[:id] has value "1".

Because you're trying to point the root_path :

localhost:3000

there is no param :id bound, thus:

User.find(params[:id])

Throws the exception.

If you want to have it "the proper way", modify your config/routes.rb :

root "users#profile"
get "profile" => "users#profile"

and inn your UserController :

class UserController < ApplicationController
  # ...
  def profile
    @user = current_user # or any other logic relevant to fetching currently logged in User
  end
end

assuming that you have current_user method implemented, and it returns proper User

However, you have to be aware - setting the "profile" as a root will cause non-logged in users to see error page.

Hope that helps!

Update - moving some template to partial

You can extract the code you need from your app/views/users/show.html.erb . Let's say, it's content is something like:

<h3><%= @user.name %></h3>
<small><%= @user.bio %></small>

You can extract it to partial app/views/users/_user_details.html.erb , so it has content:

<h3><%= user.name %></h3>
<small><%= user.bio %></small>

Please note, the @ are removed from here , and in your app/views/users/show.html.erb , you can delete all the code an replace it with:

<%= render partial: "user_details", locals: { user: @user } %>

The same might be used in your app/views/pages/home.hmtl.erb like:

<% if logged_in? %>
  <%= render partial: "user_details", locals: { user: @user } %>
<% end %>

Assuming, in your PagesController you have something like:

class PagesController < ApplicationController
  def home
    @user = current_user
  end
end

The show action is looking for params[:id], but there is no id set during the login.

Try to get the id from your current_user:

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

The condition may help you to get the user's profile when you want to show the profile of other users, as an admin for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM