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

Raise ArgumentError if :renderable object does not respond to #render_in #50665

Merged

Conversation

seanpdoyle
Copy link
Contributor

Detail

When calling render with a :renderable argument, ensure that the object responds to #render_in. If it doesn't, raise an ArgumentError.

Additional Information

This commit also adjusts the ArgumentError that when a :partial argument isn't Active Model compatible. Prior to this commit, the message used : as a prefix to to_partial_path. This commit replaces that with a # prefix to denote that it's expected to be an instance method on the object.

Checklist

Before submitting the PR make sure the following are checked:

  • This Pull Request is related to one change. Changes that are unrelated should be opened in separate PRs.
  • Commit message has a detailed description of what changed and why. If this PR fixes a related issue include it in the commit message. Ex: [Fix #issue-number]
  • Tests are added or updated if you fix a bug or add a feature.
  • CHANGELOG files are updated for the changed libraries if there is a behavior change or additional feature. Minor bug fixes and documentation changes should not be included.

@rails-bot rails-bot bot added the actionview label Jan 9, 2024
@seanpdoyle seanpdoyle force-pushed the action-view-renderable-argument-error branch from 09f0420 to 3a6c573 Compare January 9, 2024 04:55
@@ -5,6 +5,10 @@ class Template
# = Action View Renderable Template for objects that respond to #render_in
class Renderable # :nodoc:
def initialize(renderable)
unless renderable.respond_to?(:render_in)
raise ArgumentError, "'#{renderable.inspect}' is not a renderable object. It must implement #render_in."
Copy link
Member

Choose a reason for hiding this comment

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

I think its unclear from the PR description what problem this is trying to solve.

If the goal is just to raise a friendlier error than NoMethdError in render, then I think we should rescue that when it happens and raise a friendlier message there instead of adding a (slow) respond_to? check to the happy path of Renderable.

Copy link
Member

Choose a reason for hiding this comment

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

I was about to say that. We don't slow down happy path to help developers to not make self-inflected mistakes. If you know about the : renderable object I'm supposing you know that object needs to respond to render_in. I'm ok with raising a better message when they don't, but not on the happy path.

Copy link
Contributor Author

@seanpdoyle seanpdoyle Jan 9, 2024

Choose a reason for hiding this comment

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

I've moved this out of the class and back to TemplateRenderer. It mimics similar ArgumentError blocks for other options like :file

@@ -41,7 +41,12 @@ def determine_template(options)
end
Template::Inline.new(options[:inline], "inline template", handler, locals: keys, format: format)
elsif options.key?(:renderable)
Template::Renderable.new(options[:renderable])
renderable = options[:renderable]
unless renderable.respond_to?(:render_in)
Copy link
Member

Choose a reason for hiding this comment

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

This still adds overhead in the happy path

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've changed this to rescue from NoMethodError. Is that what you had in mind?

…ender_in`

When calling `render` with a `:renderable` argument, ensure that the
object responds to `#render_in`. If it doesn't, raise an
`ArgumentError`.

This commit also adjusts the `ArgumentError` that when a `:partial`
argument isn't Active Model compatible. Prior to this commit, the
message used `:` as a prefix to `to_partial_path`. This commit replaces
that with a `#` prefix to denote that it's expected to be an instance
method on the object.
@seanpdoyle seanpdoyle force-pushed the action-view-renderable-argument-error branch from 896bc8a to b3bb06a Compare January 9, 2024 21:01
@rafaelfranca rafaelfranca merged commit f3d96c2 into rails:main Jan 9, 2024
3 of 4 checks passed
@seanpdoyle seanpdoyle deleted the action-view-renderable-argument-error branch January 9, 2024 22:06
jonathanhefner added a commit to jonathanhefner/rails that referenced this pull request Jan 10, 2024
Follow-up to rails#50665.

Unconditionally converting `NoMethodError` to `ArgumentError` can mask a
legitimate `NoMethodError` from within the `render_in` method.  This
commit adds a check to prevent that.
jonathanhefner added a commit to jonathanhefner/rails that referenced this pull request Jan 10, 2024
Follow-up to rails#50665.

Unconditionally converting `NoMethodError` to `ArgumentError` can mask a
legitimate `NoMethodError` from within the `render_in` method.  This
commit adds a check to prevent that.
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

3 participants