加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 堆栈级别太深

发布时间:2020-12-17 02:47:10 所属栏目:百科 来源:网络整理
导读:您好我收到了“Stack level too deep”错误,我很确定它是从这个模型生成的.我知道它与递归调用有关,但到目前为止我无法找到它,谢谢. class Character ActiveRecord::Base # Associations belongs_to :user # Validations validates :name,:presence = true,:
您好我收到了“Stack level too deep”错误,我很确定它是从这个模型生成的.我知道它与递归调用有关,但到目前为止我无法找到它,谢谢.

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,intelligence: 0},:magi    => {strength: -3,endurance: -2,wisdom: 3,:ranger  => {strength: -2,dexterity: 2,charisma: 0,wisdom: -3,:cleric  => {strength: 2,dexterity: -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

服务器日志:

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 – 堆栈级别太深:

activerecord (4.0.2) lib/active_record/attribute_methods/read.rb:85:in `'

解决方法

您的代码有三个问题:

>您正在使用类作为属性,
>你很困惑:符号和“字符串”.downcase,
>你正在使用self.name(属性)认为它是一个不同的setter.

不要上课.这是一个保留的关键字.
这些线条会让ruby非常困惑:

validates :class,:presence => true

self.class = _class.downcase

另外,我假设您的数据库表中有一个类列.您应该将其重命名为character_class或rpg_class.

符号和字符串

您的self.classes方法返回一个哈希,其键是符号.然而,稍后您尝试使用字符串访问它:

_attributes = Character.classes[_class.downcase]

虽然确实如此:foobar.downcase什么都不做,你不能用“Foobar”.downcase访问这些值.
要解决这个问题,您可以:

>使用Character.classes [_class.to_sym]
>使用HashWithIndifferentAccess

无论如何,使用memoization可以改进该方法.
目前,您正在为每次调用重新创建哈希哈希值.相反,您可以将其保存在变量中,并仅在第一次创建它.

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

或者,更好的是,使用常量:

CHAR_CLASSES = { #.....

def self.classes
  CHAR_CLASSES
end

名称

我看到你已经有了这个验证:

validates :name,:length => { minimum: 2,format: { with: /A[a-zA-Z]+Z/ }

这意味着你的数据库表中有一个名称列,它应该是一个匹配特定格式的字符串(只有2到20之间的字母).

有了这个,让我们来看看这段代码:

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

在此局部范围中,name是包含符号的变量(例如:strength),value是Fixnum.
但是,当您执行self.name = value时,您将Fixnum分配给对象属性名称.

我看不到你在哪里定义像strength =或dexterity =这样的方法.我假设他们是桌上的专栏.

在那种情况下,这应该工作:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读