I have been stuck on this issue for some time now, but keep skipping over it. If I follow the cop guidelines here and change this to && my routes break. They are connected to my routes via:
# Override Error Codes
match '/404', to: 'error#four_oh_four', via: :all
match '/422', to: 'error#four_twenty_two', via: :all
match '/500', to: 'error#five_hundred', via: :all
Do you recommend disabling this cop for this issue or is there a better way to adjust this?
class ErrorController < ApplicationController
before_filter :ensure_trailing_slash
before_action :load_log_service
def javascript_disabled
@log_service.capture_message(view_context.time_stamp('javascript_disabled'), 'error_scope')
render_error_application_requirements t('system_requirements.minimum_settings.javascript_disabled')
end
def system_requirements
@log_service.capture_message(view_context.time_stamp('system_requirements'), 'error_scope')
render_error_application_requirements t('system_requirements.minimum_settings.system_requirements')
end
def browser_upgrade_required
@log_service.capture_message(view_context.time_stamp('browser_upgrade_required'), 'error_scope')
render_error_application_requirements t('system_requirements.minimum_settings.browser_upgrade_required')
end
def four_oh_four
@log_service.capture_message(view_context.time_stamp('four_oh_four'), 'error_code')
render_error_status_code('Page Not Found', '404', t('system_requirements.response_code.four_oh_four'))
end
# four_twenty_two, five_hundred :: no custom report needed, they are picked up by the sentry gem
def four_twenty_two
render_error_status_code('Application Error', '422', t('system_requirements.response_code.four_twenty_two'))
end
def five_hundred
render_error_status_code('Application Error', '500', t('system_requirements.response_code.five_hundred'))
end
private
def render_error_application_requirements(title)
@title = title
render 'errors/application_requirements', layout: 'errors/application_requirements' and return
end
def render_error_status_code(title, error_code, error_msg)
@title = title
@error_code = error_code
@error_msg = error_msg
render 'errors/status_code', layout: 'errors/status_code', status: @error_code and return
end
def load_log_service
@log_service = LogService.new
end
end
I think your lack of parens around the arguments to your render
calls here is confusing you. &&
has higher precedence than and
and the difference is changing how Ruby identifies the arguments to render
.
Guessing is no fun though, let's find out for sure. MRI Ruby includes Ripper
which allows us to inspect how an expression will be parsed.
require 'ripper'
require 'pp'
and
Ripper.sexp("render 'errors/application_requirements', layout: 'errors/application_requirements' and return")
[:program,
[[:binary,
[:command,
[:@ident, "render", [1, 0]],
[:args_add_block,
[[:string_literal,
[:string_content, [:@tstring_content, "errors/status_code", [1, 8]]]],
[:bare_assoc_hash,
[[:assoc_new,
[:@label, "layout:", [1, 29]],
[:string_literal,
[:string_content,
[:@tstring_content, "errors/status_code", [1, 38]]]]],
[:assoc_new,
[:@label, "status:", [1, 59]],
[:var_ref, [:@ivar, "@error_code", [1, 67]]]]]]],
false]],
:and,
[:return0]]]]
&&
Ripper.sexp("render 'errors/application_requirements', layout: 'errors/application_requirements' && return")
[:program,
[[:command,
[:@ident, "render", [1, 0]],
[:args_add_block,
[[:string_literal,
[:string_content, [:@tstring_content, "errors/status_code", [1, 8]]]],
[:bare_assoc_hash,
[[:assoc_new,
[:@label, "layout:", [1, 29]],
[:string_literal,
[:string_content,
[:@tstring_content, "errors/status_code", [1, 38]]]]],
[:assoc_new,
[:@label, "status:", [1, 59]],
[:binary,
[:var_ref, [:@ivar, "@error_code", [1, 67]]],
:"&&",
[:return0]]]]]],
false]]]]
The output from Ripper isn't the easiest thing to read but if we pay close attention to the indentation of those function call we can see that the and
case is calling render(... '..._requirements') and return
while the &&
case is calling render(... '..._requirements' && return)
. Those two expressions are going to have very different behaviors.
Like a comment under your Post, indeed you don't need to return
here.
However if you still want to use return
and have it following RuboCop style, try wrapping render params with brackets.
render('errors/status_code', layout: 'errors/status_code', status: @error_code) && return
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.