【问题标题】:How to avoid the error on nil object如何避免 nil 对象上的错误
【发布时间】:2012-07-06 13:58:03
【问题描述】:

记录 id 116 不存在,因此它应该将 nil 返回到 @conversation。
我试图让它在它为零时重定向,但是当我访问 example.com/messages/show?id=116 时它仍然显示错误。

错误是

未定义的方法`is_participant?'对于 nil:NilClass

我肯定看到存在于
中的“is_participant”方法 /usr/local/lib/ruby/gems/1.9.1/gems/mailboxer-0.7.0/app/models/conversation.rb

messages_controller.rb

def show
  @conversation = Conversation.find_by_id(params[:id])

  unless @conversation.is_participant?(current_user)
    flash[:alert] = "You do not have permission to view that conversation."
    redirect_to :controller => 'messages', :action => 'received'
  end

  @messages = Message.find_by_id(params[:id])
  current_user.read(@conversation)    
end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 error-handling controller null


    【解决方案1】:

    在调用方法之前,您需要检查 @conversation 是否不为零。试试

    unless @conversation.present? && @conversation.is_participant?(current_user)
    

    【讨论】:

      【解决方案2】:

      您可以检查是否存在值或救援该错误。

      def show
        @conversation = Conversation.find_by_id(params[:id])
      
        redirect_to somewhere_path if @conversation.nil?
      
        unless @conversation.is_participant?(current_user)
          flash[:alert] = "You do not have permission to view that conversation."
          redirect_to :controller => 'messages', :action => 'received'
        end
      
        @messages = Message.find_by_id(params[:id])
        current_user.read(@conversation)    
      end
      

      或救援!

      def show
        @conversation = Conversation.find_by_id(params[:id])
      
        unless @conversation.is_participant?(current_user)
          flash[:alert] = "You do not have permission to view that conversation."
          redirect_to :controller => 'messages', :action => 'received'
        end
      
        @messages = Message.find_by_id(params[:id])
        current_user.read(@conversation)    
      
      rescue NoMethodError
        redirect_to somewhere_path
      end
      

      注意,救援方式不是很友好,因为它可以救援其他错误,让你很难调试一些错误。例如,如果 current_user 没有名为 read 的方法,它会抛出错误并在那里捕获,而您不会注意到它来自那里。

      【讨论】:

        【解决方案3】:

        Christoph Petschnig 的回答是正确的,只是想提一下有一个很好的简写方式

        unless @conversation.present? && @conversation.is_participant?(current_user)
        

        这是

        unless @conversation.try(:is_participant? , current_user)
        

        try 将返回 nil is @conversation is nil 最终在 if 语句中计算为 false。

        【讨论】:

          猜你喜欢
          • 2022-11-16
          • 1970-01-01
          • 1970-01-01
          • 2017-10-21
          • 2019-11-23
          • 1970-01-01
          • 1970-01-01
          • 2021-09-13
          • 1970-01-01
          相关资源
          最近更新 更多