【问题标题】:Rails: undefined method `capitalize' for nil:NilClassRails:nil:NilClass的未定义方法`capitalize'
【发布时间】:2013-08-11 12:55:48
【问题描述】:

我有一个这样的商店控制器:

class StoreController < ApplicationController

  helper_method :product_type

  def store
    cat=params[:cat]
    subcat=params[:subcat]
    if cat.empty?
        @store=SubCategory.find_by_name(params[:subcat]).products.where(product_type: params[:type]).paginate(:page => params[:page], :per_page => 12)
        @subcat=params[:subcat]
        @cat=""
    else
        @store=Category.find_by_name(params[:cat]).products.where(product_type: params[:type]).paginate(:page => params[:page], :per_page => 12)
        @cat=params[:cat]
        @subcat=""
    end
    product_type
  end

  def show
    @show=Product.where(product_type: params[:type]).paginate(:page => params[:page], :per_page => 12)
    product_type
  end

  def product
    @product=Product.find(params[:product_id])
    product_type
  end

  def product_type
    @type=params[:type]
  end

end  

无论如何,我首先调用 show 操作。因此,@type 变量本身就在那里获得了它的价值。为了使 @type 变量在所有方法中可用,我在所有其他方法中调用了 product_type 方法。

我将所有这些变量称为部分下拉列表,它是一个下拉列表,对整个网站都是通用的,就像一个标题,像这样:-

<%=link_to "T-shirt", store_path(cat:"",subcat:"tshirts",type: @type) %>  

问题是,除了产品方法之外,我可以在 StoreController 的所有方法中浏览此下拉链接。意思是,当我通过商店调用下拉列表中的链接时,显示页面它工作正常,但通过产品页面调用时会引发以下错误。

nil:NilClass 的未定义方法 `capitalize'

@type 包含我正在大写的字符串。我在哪里做错了?

我的store.html.erb有这一行

<h1><%= @type.capitalize+"'s " + @subcat.capitalize + @cat.capitalize %></h1>  

【问题讨论】:

  • 你做错了什么?如何显示错误发生的位置?
  • 你是什么意思'错误发生的地方'?当我从产品页面访问 dropdown 的链接时会发生这种情况。它向我抛出了上述错误。
  • @oldergod 的意思是你没有向我们展示你使用capitalize 方法的代码,这是引发错误的地方。
  • 该错误为您提供了一个强有力的线索,即您调用 capitalize 的对象未定义,因此是一个 Nil 对象。您将需要调查为什么 @type 为空。我建议安装 better_errors gem 并挖掘引发错误的位置。
  • 它扔在我使用 @type 变量的商店页面上。更新问题。

标签: ruby-on-rails ruby nomethoderror


【解决方案1】:

错误是告诉你你正在nil 上调用capitalize 方法。

我在这里看到 2 个潜在问题:

  1. 使用find_by_name
  2. 如果params[:subcat]nilparams[:cat]nil 怎么办?

如果没有找到记录,使用find_by_name不会引发异常,将返回nil

您检查params[:cat]params[:subcat] 是否已定义的条件不正确。如果缺少一些params,则可能会出现nil 值。

您可能需要检查:

if params[:cat].blank?
  # ...
end

if params[:subcat].blank?
  # ...
end

我也会使用blank? 而不是empty?(同时检查nil"")。

【讨论】:

    【解决方案2】:

    我在使用 Rails 6 应用程序时遇到了类似的问题。

    我有 2 个模型通过一对一的关系连接:

    管理模式

    class Admin < ApplicationRecord
      has_one :personal_info, dependent: :destroy
    
      accepts_nested_attributes_for :personal_info, update_only: true, allow_destroy: 
    end
    

    个人信息模型

    class PersonalInfo < ApplicationRecord
      before_save :personal_info_capitalize
    
      # This is an enum that can be found in app/models/concerns
      include Gender
      belongs_to :admin, optional: true
    
      private
    
      def personal_info_capitalize
        # set the personal info details to capitalize letters
        self.first_name = first_name.capitalize
        self.last_name = last_name.capitalize
      end
    end
    

    对于管理员注册和会话,我使用的是 Devise gem

    AdminsController

    class Admins::RegistrationsController < Devise::RegistrationsController
      # before_action :configure_sign_up_params, only: [:create]
    .
    .
    .
      def configure_sign_up_params
        devise_parameter_sanitizer.permit(:sign_up, keys: 
                                          [personal_info_attributes: [:first_name,
                                          :last_name]])
      end
    end
    

    但是,当我尝试创建一个新的管理员时,它会抛出错误:

    NoMethodError (undefined method `capitalize' for nil:NilClass):
    

    当我查看日志时,我看到以下内容:

    Started POST "/admins" for 127.0.0.1 at 2020-08-20 12:09:19 +0100
    
    Processing by Admins::RegistrationsController#create as HTML
    
    Parameters: {"authenticity_token"=>"+RcJcpyO7mh+DmWOJ0IsymbuIascduIamDI+8RcUxWukL5B+aNAlKlgbqNzanW1EZIJ5WCs3bmV9OI+PLRI43g==", "admin"=>{"personal_info_attributes"=>{"first_name"=>"Promise", "last_name"=>"Chukwuenyem"}, "email"=>"admin@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign Up"}
    
    Unpermitted parameter: :personal_info_attributes
    

    这是我修复它的方法

    问题是调用sign_up 参数的回调被注释掉了。因此,AdminsController 不允许使用 personal_info attributes

    我只是取消注释 AdminsController 中的 configure_sign_up_params before_action 以允许这些参数:

    class Admins::RegistrationsController < Devise::RegistrationsController
      before_action :configure_sign_up_params, only: [:create]
    .
    .
    .
      def configure_sign_up_params
        devise_parameter_sanitizer.permit(:sign_up, keys: 
                                          [personal_info_attributes: [:first_name,
                                          :last_name]])
      end
    end
    

    就是这样。

    我希望这会有所帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      相关资源
      最近更新 更多