更新后的Rails帮助错误NoMethodError



当我更新我的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

相关内容

  • 没有找到相关文章

最新更新