【问题标题】:Change the url based on current_user - ROR根据 current_user 更改 url - ROR
【发布时间】:2017-08-09 18:49:04
【问题描述】:

例如,我有一个帖子控制器,它当前有一个方法 user_posts,它显示了与具有关联 ID 的用户关联的所有帖子:

def user_posts
    @user = User.find(params[:id])
    @posts = @user.posts.all
end

当帖子的 ID 与我的 current_user 相同时,我希望 url 为:foo.com/my_posts;我该怎么做?目前我的路线是这样设置的:

get 'user/posts/:id', to: 'posts#user_posts', as: 'user/posts'

我知道我可以为 my_posts 创建一个全新的控制器操作,但我想知道是否有办法在配置/路由中做到这一点。

例如,如果我浏览整个网站并点击显示“用户帖子”的链接,我希望转到用户帖子,如果该用户恰好是我,我希望 URL 显示 website.com/my_posts

【问题讨论】:

    标签: ruby-on-rails url routes controller-action


    【解决方案1】:

    如果我理解得很好,你有一个用户列表(包括当前连接的用户),每个用户都有一个链接“用户帖子”来查看用户的帖子。

    你可以这样做:

    观看次数

    在您的视图中,根据用户 ID 更改用户帖子链接。当您遍历您的用户时,检查user 的 id 是否与当前登录的用户相同。如果是,请将链接更改为/my_posts 路由,如下所示:

    <% if user.id == current_user.id %>
      <%= link_to "My posts", my_posts_path %>
    <% else %>
      <%= link_to "User posts", user_posts_path(user) %>
    <% end %>
    

    routes.rb

    添加一个my_posts 路由,该路由指向与user/posts 相同的控制器方法。

    get 'user/posts/:id', to: 'posts#user_posts', as: 'user/posts'
    get 'my_posts', to: 'posts#user_posts', as: 'my_posts'
    

    控制器

    在你的控制器方法中,我们需要实例化@user 来获取它的帖子。如果参数中没有:id(如/my_posts 路由),则将@user 设置为current_user。如果传递了:id,则通过从数据库中获取@user 来设置它。

    def user_posts
        @user = params[:id].present? ? User.find(params[:id]) : current_user
        @posts = @user.posts.all
    end
    

    无需检查 routes.rb 文件。这很简单,更像是“Rails”。

    这是你要找的吗?

    【讨论】:

    • 完美!是的,这正是我想要的。简单而优雅的答案。更详细地解释每件作品,我将奖励赏金。
    • 很高兴能帮上忙!我用详细的解释编辑了我的答案。
    【解决方案2】:

    据我所知 - 不。可以在routes 重定向路由中创建并检查一些条件(来自文档的示例):

    get 'jokes/:number', to: redirect { |params, request|
      path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp")
      "http://#{request.host_with_port}/#{path}"
    }
    

    但是在routes 中检查current user 是不可能的。重定向可以在控制器中实现,如前所述,使用两个单独的操作。

    还有一个小技巧 - 如果您使用 html.erb (slim/haml),则从一开始就生成“正确”路线。对于当前用户的帖子链接可以生成不是像往常一样user/posts/:id,而是/my_posts(可以毫无问题地检查当前用户ID)并定义两个路由:

    get 'user/posts/:id', to: 'posts#user_posts', as: 'user/posts'
    get 'my_posts', to: 'posts#user_posts', as: 'my_posts'
    

    在控制器中检查request.path 以查找用户:

    user = request.path == '/my_posts' ? current_user : User.find(params[:id])
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      我猜你不想使用帖子控制器的 index 方法,因为你使用它来显示所有用户的所有帖子,但你仍然可以使用它。方法如下:

      class PostsContoller < ApplicationController
        def index
          @posts = if params[:user_id].present?
                     User.find(params[:user_id]).posts
                   else
                     Post.all
                   end
        end
      end
      

      然后在您的路线文件中执行以下操作:

      resources :posts
      resources :users do
        resources :posts
      end
      

      这允许帖子成为第一类资源以及嵌套资源。现在,当您转到 /posts/ 时,您会收到所有帖子,但是当您转到 /users/:user_id/posts 时,您只会收到来自给定用户的帖子。

      在您的应用中,当您需要链接到所有用户的所有帖子时,您可以这样做

      posts_path

      当您需要链接到用户的帖子时,您可以这样做

      user_posts_path(user)

      【讨论】:

      • 如果帖子是我的,我希望将网址更改为 /my_posts。
      猜你喜欢
      • 2010-12-19
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多