Home > Blockchain >  "nil can't be coerced into Integer" when assign variable (only)
"nil can't be coerced into Integer" when assign variable (only)

Time:02-17

ruby '2.7.3' rails (6.1.4.1)

Looks strange:

When I query some (some specific) rows in DB using activerecord and try to assign it to a variable, it raises "nil can't be coerced into Integer"

But when I don't try to assign it to a variable, it works:

Recipient.find(45638)
 => #<Recipient id: 45638, company_id: 7, callout_id: 18, phone: "***", created_at: "2022-02-14 02:14:04.816032000  0000", updated_at: "2022-02-15 06:50:37.828979000  0000", payload: {"first_name"=>"", "last_name"=>"", "lead_id"=>"388014"}, started_at: nil, finished_at: 1644907333994, call_duration: 95, call_result: nil, report_data: {"Recording"=>"...", "UF_CRM_1601886091616"=>"76"}, job_status: "longCallWithResult", job_id: "2105242339", aasm_state: "finished", attempts: 1, tag: "...", tag_payload: {}, code: "37cca71006817c4f9e2e172d4e0afe80", schedule_at: "2022-02-11 09:07:47.000000000  0000", synced_to_external_crm: false> 

2.7.3 :035 > recipient = Recipient.find(45638)
Traceback (most recent call last):
TypeError (nil can't be coerced into Integer)

It happens only with specific rows in DB. Not only with model object, but with ActivRecord::Relation objects also:

Works:

recipients = Recipient.where(callout_id: 18).where('schedule_at IS NULL OR schedule_at <= ?', DateTime.current).limit(1).offset(5)

 => #<ActiveRecord::Relation [#<Recipient id: 45640, company_id: 7, callout_id: 18, phone: "***", created_at: "2022-02-14 04:59:10.175701000  0000", updated_at: "2022-02-15 06:50:38.224724000  0000", payload: {"firs... 

Doesn't work:

2.7.3 :045 > recipients = Recipient.where(callout_id: 18).where('schedule_at IS NULL OR schedule_at <= ?', DateTime.current).limit(1).offset(6)

Traceback (most recent call last):
TypeError (nil can't be coerced into Integer)

Same issue happens with different models:

Model 'Callout':

2.7.3 :001 > callout = Callout.find 18
 => #<Callout id: 18, company_id: 7, name: "***", token: [FILTERED], created_at: "2021-12-19 13:50:51.383907000  0000", updated_at: "2022-02-08 09:19:20.153542000  0000", auto_queue: true> 

2.7.3 :002 > callout = Callout.find 17
Traceback (most recent call last):
TypeError (nil can't be coerced into Integer)

2.7.3 :003 > Callout.find 17
 => #<Callout id: 17, company_id: 1, name: "***", token: [FILTERED], created_at: "2021-11-27 11:07:30.927895000  0000", updated_at: "2022-02-14 07:59:24.154910000  0000", auto_queue: false> 

2.7.3 :004 > Callout.find 18
 => #<Callout id: 18, company_id: 7, name: "***", token: [FILTERED], created_at: "2021-12-19 13:50:51.383907000  0000", updated_at: "2022-02-08 09:19:20.153542000  0000", auto_queue: true> 

Model 'Company':

2.7.3 :005 > Company.find 7
 => #<Company id: 7, name: "***", created_at: "2021-12-19 13:39:12.045709000  0000", updated_at: "2021-12-19 13:39:12.045709000  0000", balance: 0, api_token: [FILTERED]> 

2.7.3 :006 > c = Company.find 7
 => #<Company id: 7, name: "***", created_at: "2021-12-19 13:39:12.045709000  0000", updated_at: "2021-12-19 13:39:12.045709000  0000", balance: 0, api_token: [FILTERED]> 

2.7.3 :008 > Company.find 1
 => #<Company id: 1, name: "***", created_at: "2021-10-22 12:23:19.831733000  0000", updated_at: "2021-12-01 20:15:04.464389000  0000", balance: 0, api_token: [FILTERED]> 

2.7.3 :007 > c = Company.find 1
Traceback (most recent call last):
TypeError (nil can't be coerced into Integer)

Models source code:

class Recipient < ApplicationRecord
  validates :phone, presence: true, uniqueness: { scope: :callout_id }
  validates :code, presence: true, uniqueness: true
  belongs_to :company
  belongs_to :callout

  before_validation :generate_code

  private

  # Generates unique code for every recipient
  # because phone column can't be unique
  def generate_code
    if self.code.nil?
      self.code = Recipient.make_code self.phone, self.callout_id, self.payload
    end
  end

end


class Callout < ApplicationRecord
  belongs_to :company
  has_many :recipients, dependent: :destroy
  validates :company_id, presence: true
  validates :name, presence: true

  scope :auto_queue, -> { where(auto_queue: true ) }

end


class Company < ApplicationRecord

  before_validation :generate_token!

  has_many :callouts, dependent: :destroy
  has_many :recipients, dependent: :destroy
  has_many :user_companies, dependent: :destroy
  has_many :users, through: :user_companies
  has_many :invoices, dependent: :destroy
  has_many :balance_logs, dependent: :destroy

  validates :name, presence: true


  def generate_token!
    if api_token.nil?
      update! api_token: SecureRandom.hex
    end
  end

end

CodePudding user response:

That's related to some unexpected issue related to the use of --nomultiline or IRB.conf[:USE_MULTILINE] = false inside .irbrc file.

Similar issue with the hack

To avoid that issue, you can just skip using --nomultiline option, when launching your rails console.

bundle exec rails c -e production
  • Related