diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index ee6878502..2c4fd3e9f 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -36,19 +36,11 @@ class NotificationsController < ApplicationController end private - def linkable_resource_path(notification) - case notification.linkable_resource.class.name - when "Budget::Investment" - budget_investment_path @notification.linkable_resource.budget, @notification.linkable_resource - when "Topic" - community_topic_path @notification.linkable_resource.community, @notification.linkable_resource + if notification.linkable_resource.is_a?(AdminNotification) + notification.linkable_resource.link || notifications_path else - if @notification.linkable_resource.is_a?(AdminNotification) - @notification.linkable_resource.link || notifications_path - else - url_for @notification.linkable_resource - end + polymorphic_hierarchy_path(notification.linkable_resource) end end diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb index e5060dad2..ab81c76c6 100644 --- a/app/helpers/comments_helper.rb +++ b/app/helpers/comments_helper.rb @@ -41,22 +41,7 @@ module CommentsHelper end def commentable_path(comment) - commentable = comment.commentable - - case comment.commentable_type - when "Budget::Investment" - budget_investment_path(commentable.budget_id, commentable) - when "Legislation::Question" - legislation_process_question_path(commentable.process, commentable) - when "Legislation::Annotation" - legislation_process_draft_version_annotation_path(commentable.draft_version.process, commentable.draft_version, commentable) - when "Topic" - community_topic_path(commentable.community, commentable) - when "Legislation::Proposal" - legislation_process_proposal_path(commentable.legislation_process_id, commentable) - else - commentable - end + polymorphic_hierarchy_path(comment.commentable) end def user_level_class(comment) diff --git a/config/initializers/routes_hierarchy.rb b/config/initializers/routes_hierarchy.rb new file mode 100644 index 000000000..f440e7663 --- /dev/null +++ b/config/initializers/routes_hierarchy.rb @@ -0,0 +1,58 @@ +# This module is expanded in order to make it easier to use polymorphic +# routes with nested resources. +# HACK: is there a way to avoid monkey-patching here? Using helpers is +# a similar use of a global namespace too... +module ActionDispatch::Routing::UrlFor + def resource_hierarchy_for(resource) + case resource.class.name + when "Budget::Investment" + [resource.budget, resource] + when "Legislation::Annotation" + [resource.draft_version.process, resource.draft_version, resource] + when "Legislation::Proposal", "Legislation::Question" + [resource.process, resource] + when "Topic" + [resource.community, resource] + else + resource + end + end + + def polymorphic_hierarchy_path(resource) + # Unfortunately, we can't use polymorphic routes because there + # are cases where polymorphic_path doesn't get the named routes properly. + # Example: + # + # polymorphic_path([legislation_proposal.process, legislation_proposal]) + # + # That line tries to find legislation_process_legislation_proposal_path + # while the correct route would be legislation_process_proposal_path + # + # We probably need to define routes differently in order to be able to use + # polymorphic_path which might be possible with Rails 5.1 `direct` and + # `resolve` methods. + + resources = resource_hierarchy_for(resource) + + case resource.class.name + when "Budget::Investment" + # polymorphic_path would return budget_budget_investment_path + budget_investment_path(*resources) + when "Legislation::Annotation" + # polymorphic_path would return: + # "legislation_process_legislation_draft_version_legislation_annotation_path" + legislation_process_draft_version_annotation_path(*resources) + when "Legislation::Proposal" + # polymorphic_path would return legislation_process_legislation_proposal_path + legislation_process_proposal_path(*resources) + when "Legislation::Question" + # polymorphic_path would return legislation_process_legislation_question_path + legislation_process_question_path(*resources) + when "Poll::Question" + # polymorphic_path would return poll_question_path + question_path(*resources) + else + polymorphic_path(resources) + end + end +end diff --git a/spec/support/common_actions/notifications.rb b/spec/support/common_actions/notifications.rb index e387ce1fd..264d0ef83 100644 --- a/spec/support/common_actions/notifications.rb +++ b/spec/support/common_actions/notifications.rb @@ -32,20 +32,7 @@ module Notifications end def path_for(resource) - nested_path_for(resource) || url_for([resource, only_path: true]) - end - - def nested_path_for(resource) - case resource.class.name - when "Legislation::Question" - legislation_process_question_path(resource.process, resource) - when "Legislation::Proposal" - legislation_process_proposal_path(resource.process, resource) - when "Budget::Investment" - budget_investment_path(resource.budget, resource) - else - false - end + polymorphic_hierarchy_path(resource) end def error_message(resource_model = nil)