man*_*nis 4 ruby-on-rails ruby-on-rails-4
您好我收到了"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, 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
Run Code Online (Sandbox Code Playgroud)
服务器日志:
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
Run Code Online (Sandbox Code Playgroud)
SystemStackError - 堆栈级别太深:
activerecord (4.0.2) lib/active_record/attribute_methods/read.rb:85:in `'
Run Code Online (Sandbox Code Playgroud)
您的代码有三个问题:
class
用作属性,:symbols
和"String".downcase
,self.name
(属性)认为它是一个不同的二传手.不要用class
.这是一个保留的关键字.
这些线条会让ruby非常困惑:
validates :class, :presence => true
self.class = _class.downcase
Run Code Online (Sandbox Code Playgroud)
另外,我假设class
您的数据库表中有一列.你应该把它重命名为character_class
或者像rpg_class
.
您的self.classes
方法返回Hash
其键是符号的方法.然而,稍后您尝试使用字符串访问它:
_attributes = Character.classes[_class.downcase]
Run Code Online (Sandbox Code Playgroud)
虽然:foobar.downcase
确实无能为力,但您无法访问这些值"Foobar".downcase
.
要解决这个问题,您可以:
Character.classes[_class.to_sym]
HashWithIndifferentAccess
无论如何,可以通过使用memoization来改进该方法.
目前,您正在为每次调用重新创建哈希哈希值.相反,您可以将其保存在变量中,并仅在第一次创建它.
def self.classes
@char_classes ||= { fighter: { #...
end
Run Code Online (Sandbox Code Playgroud)
或者,更好的是,使用常量:
CHAR_CLASSES = { #.....
def self.classes
CHAR_CLASSES
end
Run Code Online (Sandbox Code Playgroud)
我看到你已经有了这个验证:
validates :name, :presence => true, :uniqueness => true, :length => { minimum: 2, maximum: 20 }, format: { with: /\A[a-zA-Z]+\Z/ }
Run Code Online (Sandbox Code Playgroud)
这意味着你name
在数据库表中有一个列,它应该是一个String
匹配的特定格式(只有2到20之间的字母).
有了这个,让我们来看看这段代码:
_attributes.each do |name, value|
self.name += value
end
Run Code Online (Sandbox Code Playgroud)
在这个局部范围内,name
是一个包含Symbol
(例如:strength
)并且value
是a 的变量Fixnum
.
当你这样做self.name += value
,但是,你是分配Fixnum
给对象属性 name
.
我看不出你在哪里定义像strength=
或的方法dexterity=
.我假设他们是桌上的专栏.
在那种情况下,这应该工作:
self.public_send("#{name}=", value)
# or just 'send' if it's a private method
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8077 次 |
最近记录: |