Изменить URL на основе current_user - ROR

Скажем, например, у меня есть контроллер сообщений, который в настоящее время имеет метод user_posts который показывает все сообщения, которые связаны с пользователем со связанным идентификатором, следующим образом:

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

Я хочу, чтобы URL был: foo.com/my_posts когда сообщения имеют тот же идентификатор, что и мой current_user; Как бы я это сделал? в настоящее время мои маршруты настроены так:

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

Я знаю, что мог бы создать совершенно новое действие контроллера для my_posts, но я хочу знать, есть ли способ сделать это в конфигурации / маршрутах.

Если, например, я просматриваю весь сайт и нажимаю на ссылку с надписью "посты пользователей", я буду ожидать посты пользователей, и если этот пользователь окажется мной, я бы хотел, чтобы URL отображался website.com/my_posts

3 ответа

Решение

Если я хорошо понимаю, у вас есть список пользователей (включая подключенного в данный момент пользователя), и у каждого есть ссылка "сообщения пользователя" для просмотра сообщений пользователя.

Вы можете просто сделать:

Просмотры

По вашему мнению, измените ссылку на сообщение пользователя в соответствии с идентификатором пользователя. Когда вы просматриваете своих пользователей, проверьте, userID совпадает с текущим вошедшим пользователем. Если да, измените ссылку на /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 текущему пользователю. Если :id прошло, установите @user выбирая его из БД.

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

Не нужно делать проверку в файле rout.rb. Это просто и больше похоже на "Rails".

Это то, что вы ищите?

Как я знаю - нет. Можно создать в 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}"
}

Но это невозможно проверить current user в routes, Перенаправление может быть реализовано в контроллере с помощью двух отдельных действий, как уже упоминалось.

Также доступна небольшая хитрость - генерируйте с начала "правильные" маршруты, если вы используете html.erb (Тонкий / Haml). Для сообщений текущего пользователя ссылка может быть сгенерирована не как обычно user/posts/:id но /my_posts (можно без проблем проверить текущий идентификатор пользователя) и определить два маршрута:

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])

Надеюсь, поможет.

Я предполагаю, что вы не хотели использовать метод 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)

Другие вопросы по тегам