gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 15:59:06 25 4
gpt4 key购买 nike

您好,我收到一个“堆栈级别太深”错误,我很确定它是从这个模型生成的。我知道它与递归调用有关,但到目前为止我一直无法找到它,谢谢。

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

服务器日志:
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 `'

最佳答案

您的代码存在三个问题:

  • 您正在使用 class作为属性,
  • 你很困惑:symbols"String".downcase ,
  • 您正在使用 self.name (属性)认为它是一个不同的二传手。

  • 类(class)

    不要使用 class .这是一个保留关键字。
    这些行会让 ruby​​ 非常困惑:
    validates :class, :presence => true

    self.class = _class.downcase

    另外,我假设您有一个 class数据库表中的列。你真的应该把它重命名为 character_class 之类的东西或 rpg_class .

    符号和字符串

    您的 self.classes方法返回 Hash其键是符号。然而,稍后您尝试使用字符串访问它:
    _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, :presence => true, :uniqueness => true, :length => { minimum: 2, maximum: 20 }, format: { with: /\A[a-zA-Z]+\Z/ }

    这意味着您有一个 name数据库表中的列,它应该是 String匹配特定格式(仅字母,介于 2 和 20 之间)。

    说了这么多,让我们来看看这段代码:
    _attributes.each do |name, value|
    self.name += value
    end

    在这个本地范围内, name是一个保存 Symbol 的变量(例如 :strength )和 valueFixnum .
    当您这样做时 self.name += value ,但是,您正在分配 Fixnum对象属性 name .

    我看不到你在哪里定义了像 strength= 这样的方法或 dexterity= .我假设它们是 table 上的列。

    在这种情况下,这应该有效:
    self.public_send("#{name}=", value)
    # or just 'send' if it's a private method

    关于ruby-on-rails - 堆栈级别太深,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22851017/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com