Вопрос

I'm having a store controller like this :

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  

In any case, I'm calling the show action first. So, the @type variable gets it's value there itself. So that the @type variable be available in all, methods I have called the product_type method in all other methods.

I'm calling all these variables form a partial dropdown which is a dropdown list and common to the whole site,like a header, like this:-

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

The problem is, I'm able to navigate through this dropdown links in all the methods of StoreController except the product method.Meaning, when I call the links in dropdown list via the store,show pages it works fine but it throws the following error when called via product page.

undefined method `capitalize' for nil:NilClass

The @type contains a string which I'm capitalizing. Where am I doing wrong?

My store.html.erb has this line

<h1><%= @type.capitalize+"'s " + @subcat.capitalize + @cat.capitalize %></h1>  
Это было полезно?

Решение

The error is telling you that you are calling capitalize method on nil.

I see 2 potentials issues here:

  1. Using find_by_name
  2. What if params[:subcat] is nil or params[:cat] is nil

Using find_by_name will not raise an exception if no record is found, nil will be returned.

Your conditions checking if params[:cat] or params[:subcat] are defined are not right. nil value can occur if some params are missing.

You might want to check:

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

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

I would also use blank? instead of empty? (checking for both nil and "").

Другие советы

I experienced a similar issue when working on a Rails 6 application.

I had 2 models that were connected by a one-to-one relationship:

Admin Model

class Admin < ApplicationRecord
  has_one :personal_info, dependent: :destroy

  accepts_nested_attributes_for :personal_info, update_only: true, allow_destroy: 
end

Personal Info Model

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

And for the Admin Registration and Sessions, I was using the 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

However, when I try to create a new Admin, it throws the error:

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

And when I look at my logs, I see the following:

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

Here's how I fixed it:

The issue was that the callback that will invoke the sign_up parameters was commented out. So the personal_info attributes weren't being permitted by the AdminsController.

I simply uncommented the configure_sign_up_params before_action in the AdminsController in other to permit those parameters:

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

That's all.

I hope this helps

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top