Если у вас есть один контроллер, который обрабатывает запросы по двум разным путям, то вам необходимо сообщить ему контексты, в которых он будет вызываться. Вы часто видите много кода, который выглядит примерно так:
before_filter :load_reportable
def load_reportable
if (params[:user_id])
@user = User.find(params[:user_id])
@reportable = @user
elsif (params[:post_id])
@post = Post.find(params[:post_id])
@reportable = @post
end
rescue ActiveRecord::RecordNotFound
render(:partial => 'not_found', :status => :not_found)
return false
end
Поскольку вы используете полиморфную ассоциацию, вы можете сделать что-то вроде этого:
before_filter :load_reportable
def load_reportable
unless (@reportable = @report.reportable)
# No parent record found
render(:partial => 'not_found', :status => :not_found)
return false
end
# Verify that the reportable relationship is expressed properly
# in the path.
if (params[:user_id])
unless (@reportable.to_param == params[:user_id])
render(:partial => 'user_not_found', :status => :not_found)
return false
end
elsif (params[:post_id])
unless (@reportable.to_param == params[:post_id])
render(:partial => 'post_not_found', :status => :not_found)
return false
end
end
end
Проблема с этим подходом, когда у вас есть один контроллер, который обслуживает два совершенно разных маршрута, заключается в том, что генерируются сообщения об ошибках, такие как «пользователь не найден» вместо «сообщение не найдено». Это может быть сложно сделать правильно, например, если вы не наследуете от Users :: BaseController.
Во многих случаях проще создать два независимых контроллера «отчетов», таких как пользователи / отчеты и сообщения / отчеты, в которых из модуля импортируются любые общие функции. Эти контроллеры обычно наследуются от базового контроллера, который выполняет загрузку и обработку ошибок. Базовый контроллер также может устанавливать макет, заголовок страницы и т. Д. Без необходимости повторной реализации этой функциональности для каждого контроллера субресурсов.
Альтернативой является удаление пар отчетов и запуск их в качестве собственного контроллера, когда отношение к «отчетной» записи в основном не имеет значения.