Rails вложенные ресурсы и маршрутизация - как разбить контроллеры?
У меня есть следующие модели:
- Сообщение
- Тег
- TaggedPost (из которого Post и Tag получают свои ассоциации by_many: through)
И у меня есть следующий routes.rb
файл:
resources :tags
resources :posts do
resources :tags
end
Поэтому, когда я перехожу к, скажем, /posts/4/tags
, это запустит меня в действие индекса для контроллера тега со значением post_id
, установленным в массиве параметров. Круто.
Мой вопрос заключается в том, что теперь, когда я получаю доступ к ресурсу вложенных тегов в сообщениях, должен ли я еще раз удалять контроллер тегов? Или мне нужно настроить какой-либо другой контроллер для обработки вложенных тегов в этот момент? В противном случае мне нужно построить дополнительную логику в контроллере тегов. Конечно, это можно сделать, но является ли это обычным способом обработки вложенных маршрутов и ресурсов? Код, который у меня есть в действии индекса для контроллера тегов, выглядит следующим образом:
TagsController.rb
def index
if params[:post_id] && @post = Post.find_by_id(params[:post_id])
@tags = Post.find_by_id(params[:post_id]).tags
else
@tags = Tag.order(:name)
end
respond_to do |format|
format.html
format.json {render json: @tags.tokens(params[:q]) }
end
end
Я вижу, что код в этом контроллере становится все более значительным, поскольку я планирую, что многие дополнительные ресурсы будут связаны с ресурсами тегов. Мысли о том, как это сделать?
Сводка вопросов:
- Если ресурс вложен, должен ли вложенный ресурс проходить через другой контроллер, представляющий вложенный ресурс? Это противоречит прохождению нормального контроллера, поскольку я нахожусь в примере кода, который я предоставил.
- Если да, то каким образом эти контроллеры должны быть названы и настроены?
Сообщите мне, если вам нужна дополнительная информация.
Ответы
Ответ 1
Все, что вы делаете с вложенными ресурсами, меняет URL-адрес маршрутизации. Единственное, что вам нужно сделать, это убедиться, что вы передаете правильный идентификатор (в своем случае) в контроллер тега. Наиболее распространенной ошибкой является идентификатор Can not Find ***.
если вы не ввели маршрут профиля в маршрут пользователя, он будет выглядеть следующим образом:
domain.com/user/1
domain.com/profile/2
когда вы вложите маршруты, которые были бы
domain.com/user/1/profile/2
Это все, что он делает. ничего больше. вам не нужны дополнительные контроллеры. Выполнение вложенной маршрутизации - это просто внешний вид. позволяя вашему пользователю следовать ассоциации. Самое важное в маршрутах вложенности - это убедиться, что вы сделали link_to правильным путем.
когда не вложен: это будет user_path и profile_path
когда он вложен, вам нужно будет использовать user_profile_path.
рейк-маршрут - ваш друг, чтобы узнать, как изменились маршруты.
надеюсь, что это поможет.
Ответ 2
Я считаю, что лучшим решением является разделение контроллеров:
resources :tags
resources :posts do
resources :tags, controller: 'PostTagsController'
end
И тогда у вас есть 3 контроллера. При желании вы можете наследовать
PostTagsController from TagsController, чтобы сделать что-то вроде:
class PostTagsController < TagsController
def index
@tags = Post.find(params[:post_id]).tags
super
end
end
Если разница - это только поиск тегов, вы можете:
class TagsController < ApplicationController
def tags
Tag.all
end
def tag
tags.find params[:id]
end
def index
@tags = tags
# ...
end
# ...
end
class PostTagsController < TagsController
def tags
Product.find(params[:product_id]).tags
end
end
Используйте эти методы и просто переопределите теги в наследующих контроллерах;)