当我更新我的konkurrancer时,我得到这个错误:
Started POST "/konkurrancers/rate/1" for 127.0.0.1 at 2011-05-02 18:52:31 +0200
Processing by KonkurrancersController#rate as */*
Parameters: {"utf8"=>"Ô£ô", "authenticity_token"=>"y2ut0YoqeUPT9z/5GBI1SDtzYIW
KjAtRI8fkG2e2Yi0=", "vind"=>{"ratings"=>"6"}, "id"=>"1"}
←[1m←[35mSQL (0.0ms)←[0m describe `kategoris_konkurrancers`
←[1m←[36mKonkurrancer Load (0.0ms)←[0m ←[1mSELECT `konkurrancers`.* FROM `kon
kurrancers`←[0m
←[1m←[35mCACHE (0.0ms)←[0m SELECT `konkurrancers`.* FROM `konkurrancers`
←[1m←[36mCACHE (0.0ms)←[0m ←[1mSELECT `konkurrancers`.* FROM `konkurrancers`←
[0m
←[1m←[35mTag Load (0.0ms)←[0m SELECT `tags`.* FROM `tags`
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 11))←[0m
←[1m←[35mSQL (0.0ms)←[0m SELECT COUNT(*) FROM `konkurrancers` INNER JOIN `tag
smenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmenus`.
tag_id = 12))
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 13))←[0m
←[1m←[35mSQL (0.0ms)←[0m SELECT COUNT(*) FROM `konkurrancers` INNER JOIN `tag
smenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmenus`.
tag_id = 14))
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 15))←[0m
←[1m←[35mSQL (0.0ms)←[0m SELECT COUNT(*) FROM `konkurrancers` INNER JOIN `tag
smenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmenus`.
tag_id = 16))
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 20))←[0m
←[1m←[35mSQL (0.0ms)←[0m SELECT COUNT(*) FROM `konkurrancers` INNER JOIN `tag
smenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmenus`.
tag_id = 21))
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 22))←[0m
←[1m←[35mSQL (0.0ms)←[0m SELECT COUNT(*) FROM `konkurrancers` INNER JOIN `tag
smenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmenus`.
tag_id = 23))
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 24))←[0m
←[1m←[35mSQL (0.0ms)←[0m SELECT COUNT(*) FROM `konkurrancers` INNER JOIN `tag
smenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmenus`.
tag_id = 25))
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 26))←[0m
←[1m←[35mSQL (0.0ms)←[0m SELECT COUNT(*) FROM `konkurrancers` INNER JOIN `tag
smenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmenus`.
tag_id = 29))
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT COUNT(*) FROM `konkurrancers` INNER JOIN
`tagsmenus` ON `konkurrancers`.id = `tagsmenus`.konkurrancer_id WHERE ((`tagsmen
us`.tag_id = 30))←[0m
←[1m←[35mKonkurrancer Load (0.0ms)←[0m SELECT `konkurrancers`.* FROM `konkurr
ancers` WHERE (`konkurrancers`.`cached_slug` = '1') LIMIT 1
←[1m←[36mSQL (0.0ms)←[0m ←[1mSELECT sluggable_id FROM slugs WHERE ((slugs.slu
ggable_type = 'Konkurrancer' AND slugs.name = '1' AND slugs.sequence = 1))←[0m
←[1m←[35mKonkurrancer Load (0.0ms)←[0m SELECT `konkurrancers`.* FROM `konkurr
ancers` WHERE (`konkurrancers`.`id` = 1) LIMIT 1
Completed in 390ms
NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+):
app/controllers/konkurrancers_controller.rb:7:in `rate'
Rendered C:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.3/lib/action_dispatc
h/middleware/templates/rescues/_trace.erb (15.6ms)
←[1m←[36mKonkurrancer Load (0.0ms)←[0m ←[1mSELECT `konkurrancers`.* FROM `kon
kurrancers` LIMIT 15 OFFSET 0←[0m
←[1m←[35mSQL (0.0ms)←[0m SHOW TABLES
←[1m←[36mSQL (0.0ms)←[0m ←[1mSHOW TABLES←[0m
Rendered C:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.3/lib/action_dispatc
h/middleware/templates/rescues/_request_and_response.erb (374.4ms)
Rendered C:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.3/lib/action_dispatc
h/middleware/templates/rescues/diagnostics.erb within rescues/layout (421.2ms)
My controller:
class KonkurrancersController < ApplicationController
def rate
@konkurrancer = Konkurrancer.find(params[:id])
@container = "Konkurrancer"+@konkurrancer.id.to_s
@konkurrancer.rating_score += params[:vind][:ratings].to_i
@konkurrancer.ratings += 1
@konkurrancer.save
respond_to do |format|
format.js
end
end
我的模型:
class Konkurrancer < ActiveRecord::Base
attr_accessible :ratings, :rating_score, :rating
after_update :do_foobar
def rating
self[:rating] || (rating_score/rating)
end
def to_param
self.name
end
def do_foobar
rating_score = self.rating_score
ratings = self.ratings
rating = (rating_score/ratings)
self.update_attributes(:rating => rating)
end
protected
def assign_cached_slug
self.cached_slug = self.name.gsub(/s+/, '_').gsub(/[^w-]/, '')
end
end
我的表:
rating_score => The current score
ratings => The number of ratings which led to the score
rating => The current rating
编辑:我的错误:
rancers`.`id` = 1)←[0m
←[1m←[35mAREL (1.0ms)←[0m UPDATE `konkurrancers` SET `rating_score` = 6, `rat
ings` = 1, `updated_at` = '2011-05-02 18:30:45', `rating` = 6 WHERE (`konkurranc
ers`.`id` = 1)
←[1m←[36mAREL (1.0ms)←[0m ←[1mUPDATE `konkurrancers` SET `rating_score` = 6,
`ratings` = 1, `updated_at` = '2011-05-02 18:30:45', `rating` = 6 WHERE (`konkur
rancers`.`id` = 1)←[0m
←[1m←[35mAREL (1.0ms)←[0m UPDATE `konkurrancers` SET `rating_score` = 6, `rat
ings` = 1, `updated_at` = '2011-05-02 18:30:45', `rating` = 6 WHERE (`konkurranc
ers`.`id` = 1)
←[1m←[36mSQL (41.0ms)←[0m ←[1mROLLBACK←[0m
Completed in 2397ms
SystemStackError (stack level too deep):
Rendered C:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.3/lib/action_dispatc
h/middleware/templates/rescues/_trace.erb (2.0ms)
←[1m←[35mKonkurrancer Load (1.0ms)←[0m SELECT `konkurrancers`.* FROM `konkurr
ancers` LIMIT 15 OFFSET 0
←[1m←[36mSQL (5.0ms)←[0m ←[1mSHOW TABLES←[0m
←[1m←[35mSQL (5.0ms)←[0m SHOW TABLES
Rendered C:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.3/lib/action_dispatc
h/middleware/templates/rescues/_request_and_response.erb (610.0ms)
Rendered C:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.3/lib/action_dispatc
h/middleware/templates/rescues/diagnostics.erb within rescues/layout (676.0ms)
我的模型:
class Konkurrancer < ActiveRecord::Base
attr_accessible :ratings, :rating_score, :rating
after_update :do_foobar
after_initialize :init
def rating
self[:rating] || (rating_score/rating)
end
def init
self.rating_score ||= 0
end
def to_param
self.name
end
def do_foobar
rating_score = self.rating_score
ratings = self.ratings
rating = (rating_score/ratings)
self.update_attributes(:rating => rating)
end
protected
def assign_cached_slug
self.cached_slug = self.name.gsub(/s+/, '_').gsub(/[^w-]/, '')
end
end
def tag_tokens=(ids)
self.tag_ids = ids.split(",")
end
我的控制器:
class KonkurrancersController < ApplicationController
def rate
@konkurrancer = Konkurrancer.find(params[:id])
@container = "Konkurrancer"+@konkurrancer.id.to_s
@konkurrancer.rating_score += params[:vind][:ratings].to_i
@konkurrancer.ratings += 1
@konkurrancer.save
respond_to do |format|
format.js
end
end
end
@konkurrancer.rating_score += params[:vind][:ratings].to_i
失败,因为@konkurrancer.rating_score
为nil。
试着先初始化它,也许是0?
@konkurrancer.rating_score ||= 0
@konkurrancer.rating_score += params[:vind][:ratings].to_i
正如BaroqueBobcat下面提到的,最好把这个登录放到你的模型中:
class Konkurrancer < ActiveRecord::Base
after_initialize :init
def init
self.rating_score ||= 0
end
end
(参见如何在ActiveRecord中设置默认值?)使用after_initialize
钩子的原因)。
关于你的第二个问题:
在你的模型中,你有after_update :do_foobar
,但是你的do_foobar
方法更新了模型,它再次触发after_update :do_foobar
,并且这继续越来越深(直到你最终得到堆栈级别太深的错误)。将您的do_foobar
方法更改为以下内容(您不需要方法的前两行,它们是多余的,并且您不需要调用update_attributes
,因为这是触发错误的原因):
after_update :do_foobar
def do_foobar
self.rating = (rating_score/ratings)
end