rails rubocop use&&代替和渲染并返回

时间:2016-02-06 06:46:12

标签: ruby-on-rails refactoring rubocop

我一直坚持这个问题一段时间了,但一直在跳过它。如果我遵循这里的警察指南并将其更改为&&我的路线坏了。它们通过以下方式连接到我的路线:

  # 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

您是否建议您针对此问题禁用此警察,还是有更好的方法来调整此问题?

enter image description here

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

2 个答案:

答案 0 :(得分:4)

我认为你对这些render电话的争论缺乏帮助,这让你感到困惑。 &&的优先级高于and,区别在于改变Ruby如何识别render的参数。

虽然猜测并不好玩,但我们肯定会发现。 MRI Ruby包含Ripper,它允许我们检查表达式的解析方式。

require 'ripper'
require 'pp'

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]]]]

Ripper的输出并不是最容易阅读的内容,但是如果我们密切注意那些函数调用的缩进,我们可以看到and情况正在调用render(... '..._requirements') and return &&案例正在调用render(... '..._requirements' && return)。这两个表达式会有非常不同的行为。

答案 1 :(得分:1)

就像您帖子下的评论一样,您确实不需要return这里。

但是,如果您仍想使用return并使其遵循RuboCop样式,请尝试使用括号包装渲染参数。

render('errors/status_code', layout: 'errors/status_code', status: @error_code) && return