diff options
| author | Teddy Wing | 2017-06-14 17:50:00 +0200 | 
|---|---|---|
| committer | Teddy Wing | 2017-06-14 17:50:00 +0200 | 
| commit | b616626283a5e24d2b9996669c0978787229d9db (patch) | |
| tree | 35a985fc954467150f9e38fd5f9294768aec6e36 /app | |
| parent | 986f3bc5a785998d9832bdcdf3e570040fd34185 (diff) | |
| download | chouette-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.rb | 92 | ||||
| -rw-r--r-- | app/helpers/table_builder_helper/custom_links.rb | 61 | ||||
| -rw-r--r-- | app/helpers/table_builder_helper/url.rb | 24 | 
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  | 
