Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement helpers proxy in controller instance level #24866

Merged
merged 2 commits into from May 5, 2016

Conversation

rafaelfranca
Copy link
Member

@rafaelfranca rafaelfranca commented May 5, 2016

It is a common pattern in the Rails community that when people want to
use any kind of helper that is defined inside app/helpers they includes
the helper module inside the controller like:

module UserHelper
  def my_user_helper
    # ...
  end
end

class UsersController < ApplicationController
  include UserHelper

  def index
    render inline: my_user_helper
  end
end

This has problem because the helper can't access anything that is
defined in the view level context class.

Also all public methods of the helper become available in the controller
what can lead to undesirable methods being routed and behaving as
actions.

Also if you helper depends on other helpers or even Action View helpers
you need to include each one of these dependencies in your controller
otherwise your helper is not going to work.

We already have a helpers proxy at controller class level but that proxy
doesn't have access to the instance variables defined in the
controller.

With this new instance level helper proxy users can reuse helpers in the
controller without having to include the modules and with access to
instance variables defined in the controller.

class UsersController < ApplicationController
  def index
    render inline: helpers.my_user_helper
  end
end

There were a lot of protected instance variables in
AbsctractController::Rendering that were related to Action Controller
and Action View.

Moving to ActionController::Base's protected instance list we make it
closer to where they are really defined.
@rafaelfranca
Copy link
Member Author

@jeremy @matthewd @sgrif do you have opinions about this?

assert methods.include?(:stratego)

# fun/pdf_helper.rb
assert methods.include?(:foobar)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also assert_includes :)

@kaspth
Copy link
Contributor

kaspth commented May 5, 2016

LGTM and like the idea.

Should we make this available for Action Mailer too?

@rafaelfranca
Copy link
Member Author

Should we make this available for Action Mailer too?

Yeah, that makes sense. Neither of them are available in mailers.

@rafaelfranca
Copy link
Member Author

So, after checking mailers helpers don't use app/helpers at all, only if they are asked. That said, I'll implement only in the controller.

@rafaelfranca rafaelfranca force-pushed the actionview-helpers branch 2 times, most recently from 9ef054e to c41b823 Compare May 5, 2016 21:16
It is a common pattern in the Rails community that when people want to
:xa
use any kind of helper that is defined inside app/helpers they includes
the helper module inside the controller like:

    module UserHelper
      def my_user_helper
        # ...
      end
    end

    class UsersController < ApplicationController
      include UserHelper

      def index
        render inline: my_user_helper
      end
    end

This has problem because the helper can't access anything that is
defined in the view level context class.

Also all public methods of the helper become available in the controller
what can lead to undesirable methods being routed and behaving as
actions.

Also if you helper depends on other helpers or even Action View helpers
you need to include each one of these dependencies in your controller
otherwise your helper is not going to work.

We already have a helpers proxy at controller class level but that proxy
doesn't have access to the instance variables defined in the
controller.

With this new instance level helper proxy users can reuse helpers in the
controller without having to include the modules and with access to
instance variables defined in the controller.

    class UsersController < ApplicationController
      def index
        render inline: helpers.my_user_helper
      end
    end
@arthurnn arthurnn merged commit 58a2212 into rails:master May 5, 2016
@arthurnn
Copy link
Member

arthurnn commented May 5, 2016

❤️

prathamesh-sonpatki added a commit to prathamesh-sonpatki/rails that referenced this pull request May 6, 2016
@kaspth
Copy link
Contributor

kaspth commented May 6, 2016

Sweet ❤️

kaspth added a commit that referenced this pull request May 6, 2016
…se-notes

[ci skip] Release notes: Add PR #24866 to release notes
@diegorv
Copy link

diegorv commented May 11, 2016

❤️


# Provides a proxy to access helpers methods from outside the view.
def helpers
@_helper_proxy ||= view_context

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious - why not use view_context.some_helper_method in the controller instead of helpers.some_helper_method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because view_context is not cached and it working view_context is just an implementation detail that I plan to change some point in the future.

@rafaelfranca rafaelfranca deleted the actionview-helpers branch October 25, 2016 01:54
kaspermeyer added a commit to kaspermeyer/actionview-component that referenced this pull request Nov 11, 2019
Adds a `#helpers` method that works as a proxy for components
to access helper methods through.

Inspired by a similar feature in Rails by @rafaelfranca:
rails/rails#24866

Resolves: ViewComponent#92
kaspermeyer added a commit to kaspermeyer/actionview-component that referenced this pull request Nov 11, 2019
Adds a `#helpers` method that works as a proxy for components
to access helper methods through.

Inspired by a similar feature in Rails by @rafaelfranca:
rails/rails#24866

Resolves: ViewComponent#95
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants