【问题标题】:NoMethodError: undefined method. With if elseNoMethodError:未定义的方法。如果其他
【发布时间】:2019-07-20 15:14:36
【问题描述】:

在我的 home_controller.rb 我有这个

  def followed_movies
    @movies = current_user.followed_movies
                         .limit(12)
                         .order('movies.created_at DESC NULLS LAST').decorate
  end

  def subscriptions
    @movies = if followed_movies.any?
               followed_movies
             else
               recommended
             end
  end

但有时我会遇到这种问题:

NoMethodError: undefined method `followed_movies' for nil:NilClass
  app/controllers/home_controller.rb:35:in `followed_movies'
    .includes(:screen, :online_links)
  app/controllers/home_controller.rb:41:in `subscriptions'
    @movies = if followed_movies.any?

如何解决?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-5


    【解决方案1】:

    希望对你有帮助..

    def subscriptions 
        if current_user.followed_movies.present? 
            @movies = followed_movies 
        else 
            @movies = recommended 
        end 
     end
    

    或者 使用现在?

    在场?是来自 ActiveSupport 的 Rails 方法

    有吗?是纯 Ruby 几个要点:

    nil.any? # => NoMethodError: undefined method `any?' for nil:NilClass
     nil.present? # => false 
    [""].any? && [""].present? # => true 
    [""].any? &:present? # => false
    

    【讨论】:

      【解决方案2】:

      如果您偶尔而不是每次都遇到此问题,这意味着在调用 followed_movies 时,有时 current_usernil(没有用户登录)。

      控制器应该在运行操作之前检查用户是否登录,或者您可以更改followed_movies 方法以检查current_user 是否为nil

        def followed_movies
          @movies = 
            if current_user.present?
              current_user.followed_movies
                          .limit(12)
                          .order('movies.created_at DESC NULLS LAST')
                          .decorate
            else
              []
            end
        end
      

      如果您只想让方法在变量是否为 nil 的情况下工作,请使用安全导航运算符 &.。如果在 nil 对象上调用该方法,&. 将返回 nil

        def followed_movies
          @movies = current_user&.followed_movies
                                &.limit(12)
                                &.order('movies.created_at DESC NULLS LAST')
                                &.decorate
        end
      
        def subscriptions
          @movies = if followed_movies&.any?
                     followed_movies
                   else
                     recommended
                   end
        end
      

      使用这样编写的方法,如果followed_movies 将是nil current_usernil,那么当在subscriptions 中调用时,您将得到recommended

      【讨论】:

      • 你不应该鼓励人们做这种 (current_user&.followed_movies&.limit(12)&.order('movies.created_at DESC NULLS LAST')&.decorate) 之类的事情。
      • 我总是愿意改进我的编码标准,所以请解释您的评论。我猜你不喜欢我使用安全导航运算符?我通常更喜欢检查一个对象是否存在,如果它可能是 nil,但我认为使用安全导航器没有任何问题。
      猜你喜欢
      • 2013-04-24
      • 2015-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-01
      • 2019-06-12
      • 2013-11-14
      • 2021-07-07
      相关资源
      最近更新 更多