【问题标题】:Why root route not working with users#show?为什么 root 路由不能与 users#show 一起使用?
【发布时间】:2015-06-01 23:16:50
【问题描述】:

我尝试将此作为我的根路由root 'users#show',以便用户在登录时被带到他的个人资料,但我却遇到了这个错误:

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

当我通过<li><%= link_to "Profile", current_user %></li> 使用个人资料作为自己的标签时,这可以工作,但我不能输入root 'current_user',否则我会收到此错误:

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

感谢您的宝贵时间。

【问题讨论】:

    标签: ruby-on-rails ruby routes root


    【解决方案1】:

    实际上,您提供的错误消息指出了问题所在。

    如果您定义了根,如您提到的root "users#show",它会正确执行UsersControllershow 操作,但如果您以“标准方式”实施该操作:

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

    这里失败了,因为没有params[:id]。该值是从 url 获取的。如果您指向网址:

    localhost:3000/users/1
    

    params[:id] 的值为“1”。

    因为你试图指向root_path

    localhost:3000
    

    没有参数:id绑定,因此:

    User.find(params[:id])
    

    抛出异常。

    如果你想要“正确的方式”,修改你的 config/routes.rb

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

    和你的UserController

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

    假设您已实现 current_user 方法,并且它返回正确的 User

    但是,您必须注意 - 将“配置文件”设置为 root 会导致未登录的用户看到错误页面。

    希望有帮助!

    更新 - 将某些模板移至部分模板

    您可以从 app/views/users/show.html.erb 中提取您需要的代码。比方说,它的内容是这样的:

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

    你可以把它提取到部分app/views/users/_user_details.html.erb,所以它有内容:

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

    请注意,@ 已从此处删除,在您的 app/views/users/show.html.erb 中,您可以删除所有代码将其替换为:

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

    您的 app/views/pages/home.hmtl.erb 可能会使用相同的内容,例如:

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

    假设,在你的 PagesController 你有类似的东西:

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

    【讨论】:

    • 比我解释得更好......一如既往,Pawel!
    • 谢谢帕维尔!我一直在尝试通过实施条件来解决您提到的错误问题。我想我会保留根pages#home,然后将我带到&lt;% if logged_in? %&gt; &lt;%= render 'users#show %> 或users#profile 的表单,但随后我收到一条错误消息,因为它不是部分的。如果我把它变成一个部分,我会得到另一个错误。有什么想法吗?
    • 嘿,有可能!检查我更新的答案,以便我可以包含更多代码 sn-ps!祝你好运!
    • 谢谢你在过去的几个小时里我一直在修改你的答案。终于明白了:)感谢您的解释。
    【解决方案2】:

    如果您需要将他重定向到show 操作并显示current user 的详细信息,则将current_user 设置为@user

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

    【讨论】:

    • 再次感谢 SharVy!我不知道这是否可能,但我希望它在其他用户也可以看到配置文件的地方,所以通过将其切换到 current_user 不仅当前用户能够看到它吗?加上添加那行仍然给了我第一个错误。您认为我应该为根路由和其他所有人创建单独的配置文件吗?
    • 更新了我的答案,看看是否有帮助。是的,保留 show 动作和视图以供公众查看,并创建另一个动作,例如 dashboard 以显示自我资料。
    • 我担心提议的代码有一个明显的缺点 - 如果登录用户将尝试访问任何其他用户配置文件 (/users/1) 他将始终只看到他的数据 (current_user永远不会是“假的”,因此User.find(params[:id]) 永远不会被执行)。
    • @PawełDawczak,你是绝对正确的。更新我的答案。
    • 抱歉 SharVy 我不得不给 Pawel 支票,因为虽然你的答案似乎正确,但他的答案也是如此,他帮助我将球从他的更新中移得更远一点。我希望我们还能成为朋友;)
    【解决方案3】:

    show action 正在寻找 params[:id],但登录时没有设置 id。

    尝试从您的 current_user 获取 id:

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

    当您想显示其他用户的个人资料时,该条件可以帮助您获取用户的个人资料,例如作为管理员。

    【讨论】:

    • 请注意——“第二种”情况下的@user 将是Fixnum 而不是User——需要对find User 进行额外查询。只是说;)
    猜你喜欢
    • 2016-10-29
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 2021-06-14
    • 2012-10-09
    • 2020-03-18
    • 2017-11-21
    相关资源
    最近更新 更多