更新错误NoMethodError后Rails帮助

时间:2011-05-02 16:58:57

标签: ruby-on-rails ruby ruby-on-rails-3

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

我的控制器:

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

1 个答案:

答案 0 :(得分:2)

@konkurrancer.rating_score += params[:vind][:ratings].to_i失败,因为@konkurrancer.rating_score为零。

首先尝试将其初始化为某些内容,也许是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

(有关使用after_initialize挂钩的原因,请参阅How can I set default values in ActiveRecord?


关于你的第二个问题:

在您的模型中,您有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