ruby-on-rails – 堆栈级别太深
您好我收到了“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 `' 解决方法
您的代码有三个问题:
>您正在使用类作为属性, 类 不要上课.这是一个保留的关键字. 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] 无论如何,使用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. 我看不到你在哪里定义像strength =或dexterity =这样的方法.我假设他们是桌上的专栏. 在那种情况下,这应该工作: self.public_send("#{name}=",value) # or just 'send' if it's a private method (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |