为什么我会收到noMethodError错误?

时间:2011-03-31 20:54:42

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

这是错误:

NoMethodError in VideosController#update

undefined method `each' for #<Topic:0x1032ee330>

这是应用程序跟踪:

app/models/video.rb:19:in `assign_topics'
app/controllers/videos_controller.rb:41:in `update'
app/controllers/videos_controller.rb:40:in `update'

这是我的assign_topics方法:

def assign_topics
  if @topic_names
    self.topics = Topic.find_or_create_by_name(@topic_names)
  end
end

请注意,我正在关注此事:http://media.railscasts.com/videos/167_more_on_virtual_attributes.mov

以下是视频控制器的更新方法:

def update
    @video = current_user.videos.find(params[:id])

    respond_to do |format|
      if @video.update_attributes(params[:video])
        format.html { redirect_to(@video, :notice => 'Video was successfully updated.') }
      else
        format.html { render :action => "edit" }
      end
    end
  end

2 个答案:

答案 0 :(得分:0)

你得到的是NoMethodError Exception因为代码中的某个地方,你试图通过.each()循环一个不是数组/可枚举的东西。

根据您的例外情况,您在模型对象(主题)上调用.each(),这对于没有.each()方法是有意义的。

答案 1 :(得分:0)

我猜你的assign_topics方法有问题。 Topic.find_or_create_by_name会返回一个Topic个实例,然后您将其分配给self.topics,而self.topics可能会期待Array(或其他Enumerble );然后,更新过程将尝试使用self.topics遍历each,您就会收到错误。

你在评论中提到你尝试过这样的事情:

self.topics = @topic_names.each { |n| Topic.find_or_create_by_name(n) }

但这不起作用,因为each returns the original array所以上面的内容相当于:

@topic_names.each { |n| Topic.find_or_create_by_name(n) }
self.topics = @topic_names

并且您发现/创建的所有Topic个实例都被丢弃了。

所以,你可能会更好地使用collect这样的运气:

def assign_topics
    if @topic_names
        self.topics = @topic_names.collect { |n| Topic.find_or_create_by_name(n) }
    end
end