Изменить 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 ответа
Если я хорошо понимаю, у вас есть список пользователей (включая подключенного в данный момент пользователя), и у каждого есть ссылка "сообщения пользователя" для просмотра сообщений пользователя.
Вы можете просто сделать:
Просмотры
По вашему мнению, измените ссылку на сообщение пользователя в соответствии с идентификатором пользователя. Когда вы просматриваете своих пользователей, проверьте, 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
текущему пользователю. Если :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)