Extract commentable_path to an initializer

By doing so and including it in ActionDispatch::Routing::UrlFor, we make
it available in controllers, helpers and specs, and so we can remove the
duplication we had there with methods dealing with the same problem.

Even if monkey-patching is ugly, using a different module and executing
ActionDispatch::Routing::UrlFor.send(:include, MyModule) wouldn't make
the method available in the controller.
This commit is contained in:
Javi Martín
2018-09-17 20:16:54 +02:00
parent b49b3ade68
commit a64a290392
4 changed files with 63 additions and 41 deletions

View File

@@ -36,19 +36,11 @@ class NotificationsController < ApplicationController
end end
private private
def linkable_resource_path(notification) def linkable_resource_path(notification)
case notification.linkable_resource.class.name if notification.linkable_resource.is_a?(AdminNotification)
when "Budget::Investment" notification.linkable_resource.link || notifications_path
budget_investment_path @notification.linkable_resource.budget, @notification.linkable_resource
when "Topic"
community_topic_path @notification.linkable_resource.community, @notification.linkable_resource
else else
if @notification.linkable_resource.is_a?(AdminNotification) polymorphic_hierarchy_path(notification.linkable_resource)
@notification.linkable_resource.link || notifications_path
else
url_for @notification.linkable_resource
end
end end
end end

View File

@@ -41,22 +41,7 @@ module CommentsHelper
end end
def commentable_path(comment) def commentable_path(comment)
commentable = comment.commentable polymorphic_hierarchy_path(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
end end
def user_level_class(comment) def user_level_class(comment)

View File

@@ -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

View File

@@ -32,20 +32,7 @@ module Notifications
end end
def path_for(resource) def path_for(resource)
nested_path_for(resource) || url_for([resource, only_path: true]) polymorphic_hierarchy_path(resource)
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
end end
def error_message(resource_model = nil) def error_message(resource_model = nil)