Stack level too deep

Hello, I got the error "The stack level is too deep" and I am sure that it is generated from this model. I know this has something to do with a recursive call, but I haven’t been able to find it yet, thanks.

class Character < ActiveRecord::Base

  # Associations
  belongs_to :user

  # Validations
  validates :name, :presence => true, :uniqueness => true, :length => 
  { minimum: 2, maximum: 20 }, format: { with: /\A[a-zA-Z]+\Z/ }
  validates :race, :presence => true
  validates :class, :presence => true
  validates :user, :presence => true

  def self.races
    ["Human", "Dwarf", "Elven", "Orc", "Undead", "Demon"]
  end

  def self.classes
    {
      :fighter => {strength: 4, endurance: 3, dexterity: -2, charisma: -2, wisdom: -2, intelligence: -3}, 
      :thief   => {strength: -3,endurance: 2, dexterity: 4, charisma: 2, wisdom: -2, intelligence: 0}, 
      :magi    => {strength: -3, endurance: -2, dexterity: -2, charisma: 2, wisdom: 3, intelligence: -3}, 
      :ranger  => {strength: -2, endurance: 2, dexterity: 2, charisma: 0, wisdom: -3, intelligence: 0}, 
      :cleric  => {strength: 2,endurance: 2, dexterity: -3, charisma: -2, wisdom: 3, intelligence: 2}
    }
  end

  def set_class(_class)
    _attributes = Character.classes[_class.downcase]
    transaction do
      self.class = _class.downcase
      _attributes.each do |name, value|
        self.name += value
      end
      self.save
    end
  end
end

Server Log:

Started GET "/characters/new" for 127.0.0.1 at 2014-04-04 01:54:14 +0200
  [1m[36mActiveRecord::SchemaMigration Load (0.8ms)[0m  [1mSELECT "schema_migrations".* FROM "schema_migrations"[0m
Processing by CharactersController#new as HTML
  [1m[35mUser Load (1.5ms)[0m  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
  Rendered shared/_error_messages.html.erb (3.8ms)
  Rendered characters/new.html.erb within layouts/application (38.1ms)
Completed 500 Internal Server Error in 199ms

SystemStackError - the stack level is too deep:

activerecord (4.0.2) lib/active_record/attribute_methods/read.rb:85:in `'
+4
source share
2 answers

There are three problems in the code:

  • you use classas an attribute,
  • you are misleading :symbolsand "String".downcase,
  • you use self.name(attribute), considering it to be another installer.

Class

class. .
:

validates :class, :presence => true

self.class = _class.downcase

, , DB class. character_class rpg_class.

self.classes Hash, . , , :

_attributes = Character.classes[_class.downcase]

, :foobar.downcase , "Foobar".downcase.
, :

, memoization.
. .

def self.classes
  @char_classes ||= { fighter: { #...
end

, , :

CHAR_CLASSES = { #.....

def self.classes
  CHAR_CLASSES
end

, :

validates :name, :presence => true, :uniqueness => true, :length => { minimum: 2, maximum: 20 }, format: { with: /\A[a-zA-Z]+\Z/ }

, DB name String, ( 2 20).

:

_attributes.each do |name, value|
  self.name += value
end

name , Symbol (, :strength), value - Fixnum.
, self.name += value, Fixnum name.

, strength= dexterity=. , .

:

self.public_send("#{name}=", value)
# or just 'send' if it a private method
+5

, . , . name = 'mike'; self.name self.mike.

def set_class(_class)
  _attributes = Character.classes[_class.downcase]
  transaction do
    self.class = _class.downcase
    _attributes.each do |name, value|
      self.public_send("#{name}=", value)
    end
    self.save
  end
end
+2

Source: https://habr.com/ru/post/1534933/


All Articles