aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorTeddy Wing2017-06-14 17:50:00 +0200
committerTeddy Wing2017-06-14 17:50:00 +0200
commitb616626283a5e24d2b9996669c0978787229d9db (patch)
tree35a985fc954467150f9e38fd5f9294768aec6e36 /app
parent986f3bc5a785998d9832bdcdf3e570040fd34185 (diff)
downloadchouette-core-b616626283a5e24d2b9996669c0978787229d9db.tar.bz2
TableBuilder: Extract custom action link methods to a new class
Move `#action_links`, `#action_link_method`, and `#actions_after_policy_check` to a new class. They all depend on an action and/or a model object, so it made sense to group these together. Also, these should really be tested, and moved out of a private method context. They now live in `TableBuilderHelper::CustomLinks`. The advantage is that we now have these methods grouped together in a separate module that can be tested separately. Needed to change some things around now that they're in a class: * `obj` and `action` are now instance variables * In order to call Pundit's `policy` method, we have to call it directly on `Pundit`, since we're no longer in the context of a helper/controller/view. * Create a `UserContext` that can be passed to Pundit based on the one created in `ApplicationController`. * Rename some methods to make more sense in this new context. * Move `actions_to_http_methods` to a class constant, so we're not redefining it in every call to `method_for_action`. * Use `I18n.t` instead of `t` alone, otherwise getting the translation doesn't work. * Move `TableBuilderHelper#polymorphic_url_parts` to a new class `TableBuilderHelper::URL`. This enables us to use it in both `CustomLinks` and the `TableBuilderHelper`. We can't use it from `CustomLinks` if it's a public method in `TableBuilderHelper`, and we can't use it in `TableBuilderHelper#tbody` if it's a class method in `TableBuilderHelper`. There's a problem with the action symbols that aren't directly handled in `actions_after_policy_check`. The `:show` action was passed by the workbenches/show.html.slim template, but it doesn't appear in the resulting output even though it should. Refs #3479
Diffstat (limited to 'app')
-rw-r--r--app/helpers/table_builder_helper.rb92
-rw-r--r--app/helpers/table_builder_helper/custom_links.rb61
-rw-r--r--app/helpers/table_builder_helper/url.rb24
3 files changed, 98 insertions, 79 deletions
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index d1afcddf7..98c170b85 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -1,3 +1,6 @@
+require 'table_builder_helper/custom_links'
+require 'table_builder_helper/url'
+
# TODO: Add doc comment about neeeding to make a decorator for your collections
# TODO: Document global variables this uses
module TableBuilderHelper
@@ -100,7 +103,7 @@ module TableBuilderHelper
if column_is_linkable?(column)
# Build a link to the `item`
- polymorph_url = polymorphic_url_parts(item)
+ polymorph_url = URL.polymorphic_url_parts(item)
bcont << content_tag(:td, link_to(value, polymorph_url), title: 'Voir')
else
bcont << content_tag(:td, value)
@@ -122,12 +125,20 @@ module TableBuilderHelper
end
def build_links(item, links)
+ user_context = UserContext.new(
+ current_user,
+ referential: self.try(:current_referential)
+ )
+
trigger = content_tag :div, class: 'btn dropdown-toggle', data: { toggle: 'dropdown' } do
content_tag :span, '', class: 'fa fa-cog'
end
menu = content_tag :ul, class: 'dropdown-menu' do
- (action_links(links, item) + item.action_links).map do |link|
+ (
+ CustomLinks.new(item, user_context, links).links +
+ item.action_links
+ ).map do |link|
content_tag :li, link_to(
link.name,
link.href,
@@ -248,81 +259,4 @@ module TableBuilderHelper
def column_is_linkable?(column)
column.attribute == 'name' || column.attribute == 'comment'
end
-
- def polymorphic_url_parts(item)
- polymorph_url = []
-
- unless item.is_a?(Calendar) || item.is_a?(Referential)
- if current_referential
- polymorph_url << current_referential
- polymorph_url << item.line if item.respond_to? :line
- polymorph_url << item.route.line if item.is_a?(Chouette::RoutingConstraintZone)
- polymorph_url << item if item.respond_to? :line_referential
- polymorph_url << item.stop_area if item.respond_to? :stop_area
- polymorph_url << item if item.respond_to? :stop_points || item.is_a?(Chouette::TimeTable)
- elsif item.respond_to? :referential
- polymorph_url << item.referential
- end
- else
- polymorph_url << item
- end
-
- polymorph_url
- end
-
- # TODO: rename
- def action_links(actions, obj)
- actions_after_policy_check(actions, obj).map do |action|
- # TODO: Move that s to another method
- polymorph_url = []
-
- unless [:show, :delete].include? action
- polymorph_url << action
- end
-
- polymorph_url += polymorphic_url_parts(obj)
-
- Link.new(
- name: t("actions.#{action}"),
- href: polymorph_url,
- method: action_link_method(action)
- )
- end
- end
-
- def action_link_method(action)
- actions_to_http_methods = {
- delete: :delete,
- archive: :put,
- unarchive: :put
- }
-
- actions_to_http_methods[action] || :get
- end
-
- def actions_after_policy_check(actions, obj)
- actions.select do |action|
- # if action == :delete
- # if policy(item).present? && policy(item).destroy?
- # action
- # end
- # elsif action == :edit
- # if policy(item).present? && policy(item).update?
- # action
- # end
- # elsif action == :edit
- #
- # end
- # if (action == :delete && policy(item).present? && policy(item).destroy?) ||
- (action == :delete && policy(obj).present? && policy(obj).destroy?) ||
- (action == :delete && !policy(obj).present?) ||
- (action == :edit && policy(obj).present? && policy(obj).update?) ||
- (action == :edit && !policy(obj).present?) ||
- (action == :archive && !obj.archived?) ||
- (action == :unarchive && obj.archived?) ||
- ([:delete, :edit, :archive, :unarchive].include?(action))
- # action
- # end
- end
- end
end
diff --git a/app/helpers/table_builder_helper/custom_links.rb b/app/helpers/table_builder_helper/custom_links.rb
new file mode 100644
index 000000000..9703940d6
--- /dev/null
+++ b/app/helpers/table_builder_helper/custom_links.rb
@@ -0,0 +1,61 @@
+require 'table_builder_helper/url'
+
+module TableBuilderHelper
+ class CustomLinks
+ ACTIONS_TO_HTTP_METHODS = {
+ delete: :delete,
+ archive: :put,
+ unarchive: :put
+ }
+
+ def initialize(obj, user_context, actions)
+ @obj = obj
+ @user_context = user_context
+ @actions = actions
+ end
+
+ def links
+ actions_after_policy_check.map do |action|
+ Link.new(
+ name: I18n.t("actions.#{action}"),
+ href: polymorphic_url(action),
+ method: method_for_action(action)
+ )
+ end
+ end
+
+ def polymorphic_url(action)
+ polymorph_url = []
+
+ unless [:show, :delete].include?(action)
+ polymorph_url << action
+ end
+
+ polymorph_url += URL.polymorphic_url_parts(@obj)
+ end
+
+ def method_for_action(action)
+ ACTIONS_TO_HTTP_METHODS[action] || :get
+ end
+
+ def actions_after_policy_check
+ @actions.select do |action|
+ (action == :delete &&
+ Pundit.policy(@user_context, @obj).present? &&
+ Pundit.policy(@user_context, @obj).destroy?) ||
+ (action == :delete &&
+ !Pundit.policy(@user_context, @obj).present?) ||
+ (action == :edit &&
+ Pundit.policy(@user_context, @obj).present? &&
+ Pundit.policy(@user_context, @obj).update?) ||
+ (action == :edit &&
+ !Pundit.policy(@user_context, @obj).present?) ||
+ (action == :archive && !@obj.archived?) ||
+ (action == :unarchive && @obj.archived?) ||
+
+ # TODO: Something wrong here for actions not handled
+ ([:delete, :edit, :archive, :unarchive].include?(action))
+ end
+ end
+ end
+end
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
new file mode 100644
index 000000000..59099ee99
--- /dev/null
+++ b/app/helpers/table_builder_helper/url.rb
@@ -0,0 +1,24 @@
+module TableBuilderHelper
+ class URL
+ def self.polymorphic_url_parts(item)
+ polymorph_url = []
+
+ unless item.is_a?(Calendar) || item.is_a?(Referential)
+ if current_referential
+ polymorph_url << current_referential
+ polymorph_url << item.line if item.respond_to? :line
+ polymorph_url << item.route.line if item.is_a?(Chouette::RoutingConstraintZone)
+ polymorph_url << item if item.respond_to? :line_referential
+ polymorph_url << item.stop_area if item.respond_to? :stop_area
+ polymorph_url << item if item.respond_to? :stop_points || item.is_a?(Chouette::TimeTable)
+ elsif item.respond_to? :referential
+ polymorph_url << item.referential
+ end
+ else
+ polymorph_url << item
+ end
+
+ polymorph_url
+ end
+ end
+end