Ruby on rails 为nil:NilClass返回未定义的方法“each”?
下面是我在视图中的代码:show.html.erbRuby on rails 为nil:NilClass返回未定义的方法“each”?,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,下面是我在视图中的代码:show.html.erb <ul> <% @bullets.each do |r| %> <li><%= r.content %></li> <% end %> </ul> 以下是我在控制器中的代码:users\u controller.rb if cookies[:bullets].nil? @bullets = Bullet.all.shuffle.first(4)
<ul>
<% @bullets.each do |r| %>
<li><%= r.content %></li>
<% end %>
</ul>
以下是我在控制器中的代码:users\u controller.rb
if cookies[:bullets].nil?
@bullets = Bullet.all.shuffle.first(4)
cookies[:bullets] = @bullets.collect(&:id)
else
@bullets = []
cookies[:bullets].each do |id|
@bullets << Bullet.find(id)
end
end
这将为上的nil:NilClass返回未定义的方法“each”
<% @bullets.each do |r| %>
我想知道它为什么会这样做,以及如何修复它以发布来自数据库sqlite3表的四个随机固定项目符号内容,该表名为子弹列是内容
编辑:这是整个控制器:
class StudentsController < ApplicationController
#GET /
def index
@students = Student.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @students }
end
end
#GET /new
def new
@student = Student.new
end
#POST
def create
@student = Student.new(params[:student])
if @student.save
render :file => 'app/views/success'
else
render :file => 'app/views/students/fail'
end
end
#GET /students/{:id}
def show
@student = Student.find_by_url(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @student }
end
end
#BULLETS Randomizing /students/new.html.erb
if cookies[:bullets].nil?
@bullets = Bullet.all.shuffle.first(4)
cookies[:bullets] = @bullets.collect(&:id)
else
@bullets = []
cookies[:bullets].each do |id|
@bullets << Bullet.find(id)
end
end
#GET /students/1/edit
def edit
@student = Student.find_by_url(params[:id])
end
def update
@student = Student.find_by_url(params[:id])
respond_to do |format|
if @student.update_attributes(params[:student])
format.html { redirect_to @student, notice: 'Student was successfully updated.'}
else
format.html { render action: "edit" }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
#DELETE
def destroy
@student = Student.find_by_url(params[:id])
@student.destroy
respond_to do |format|
format.html { redirect_to students_url }
format.json { head :no_content }
end
end
end
编辑2:像这样吗
#GET /students/{:id}
def show
@student = Student.find_by_url(params[:id])
#BULLETS Randomizing /students/show.html.erb
if cookies[:bullets].nil?
@bullets = Bullet.all.shuffle.first(4)
cookies[:bullets] = @bullets.collect(&:id)
else
@bullets = []
cookies[:bullets].each do |id|
@bullets << Bullet.find(id)
end
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: @student }
end
end
看起来应该是:
#GET /students/{:id}
def show
@student = Student.find_by_url(params[:id])
#BULLETS Randomizing /students/new.html.erb
if cookies[:bullets].nil?
@bullets = Bullet.all.shuffle.first(4)
cookies[:bullets] = @bullets.collect(&:id)
else
# simpler to use an 'in list' for only 4 id's
Bullet.where("id in (?)", cookies[:bullets])
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: @student }
end
end
注意,我将cookies数组上的循环转换为一个带有“in list”的语句,这将简化为查找生成的sql
尽管如此,仍有争议的是,应将此代码推送到模型中:
class Bullet < ActiveRecord::Base
NUM_USER_BULLETS = 4
# fetch a random set of
def self.user_bullets
Bullet.all.shuffle.first(NUM_USER_BULLETS)
end
end
将代码迁移到您的模型中后,您的控制器就更简单了。看起来应该是:
#GET /students/{:id}
def show
@student = Student.find_by_url(params[:id])
#BULLETS Randomizing /students/new.html.erb
if cookies[:bullets].nil?
@bullets = Bullet.all.shuffle.first(4)
cookies[:bullets] = @bullets.collect(&:id)
else
# simpler to use an 'in list' for only 4 id's
Bullet.where("id in (?)", cookies[:bullets])
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: @student }
end
end
注意,我将cookies数组上的循环转换为一个带有“in list”的语句,这将简化为查找生成的sql
尽管如此,仍有争议的是,应将此代码推送到模型中:
class Bullet < ActiveRecord::Base
NUM_USER_BULLETS = 4
# fetch a random set of
def self.user_bullets
Bullet.all.shuffle.first(NUM_USER_BULLETS)
end
end
将代码迁移到您的模型中后,您的控制器就更简单了。我建议将随机项目符号代码重构为用于显示操作的before_过滤器,并在数据库中执行随机化,这将比加载整个表并在Ruby中执行随机化更快:
class UsersController < ApplicationController
before_filter :assign_bullets, :only => :show
# ...
private
def assign_bullets
if cookies[:bullets]
@bullets = cookies[:bullets].map { |id| Bullet.find(id) }
else
@bullets = Bullet.order('RANDOM()').limit(4)
cookies[:bullets] = @bullets.map(&:id)
end
end
end
我建议将随机项目符号代码重构为show操作的before_过滤器,并在数据库中执行随机化,这将比加载整个表并在Ruby中执行随机化更快:
class UsersController < ApplicationController
before_filter :assign_bullets, :only => :show
# ...
private
def assign_bullets
if cookies[:bullets]
@bullets = cookies[:bullets].map { |id| Bullet.find(id) }
else
@bullets = Bullet.order('RANDOM()').limit(4)
cookies[:bullets] = @bullets.map(&:id)
end
end
end
您确定项目符号表不是空的吗?即使该表是空的,Arrayfirst在收到整数参数时也会返回一个空数组not nil,并且他会显式地将@bullets初始化为if语句另一个分支中的数组。在你的控制器动作或视图中还有什么你可以发布的吗?这些代码是用来在你的表演动作中插入子弹的吗?还是用另一种方法?如果是这样的话,确保有人给它打电话。。无论是显式地从show action还是使用before_filteryeah see,它都在show action之外将该代码块移动到show action您确定项目符号表不是空的?即使该表是空的,Arrayfirst在收到整数参数时也会返回一个空数组而不是零,他显式地将@bullets初始化为if语句的另一个分支中的数组。在你的控制器动作或视图中还有什么你可以发布的吗?这些代码是用来在你的表演动作中插入子弹的吗?还是用另一种方法?如果是这样的话,确保有人给它打电话。。无论是显式地从show action还是使用before_FilteryYeh see,它都在show action之外将代码块移动到show action中小心使用RANDOM-它的格式可以是特定于数据库的。而且,如果桌子变大,它会减慢速度。更多信息请参见此处:谢谢@KevinBedell。那条线绝对值得一读。在确定解决方案之前,OP应该在他的数据上对这些不同的方法进行基准测试。当然要这样做。谢谢Brandan。使用RANDOM时要小心——它的格式可以是特定于数据库的。而且,如果桌子变大,它会减慢速度。更多信息请参见此处:谢谢@KevinBedell。那条线绝对值得一读。在确定解决方案之前,OP应该在他的数据上对这些不同的方法进行基准测试。当然要这样做。谢谢你,布兰登,还有身份证。它是否需要一些东西来代替“?”语法中的id,cookies[:bullets]基本上意味着用变量cookies[:bullets]代替?在实际查询中。哦,好的,谢谢。请允许我问一下,为什么我对这个问题的第二次编辑第一次有效,但在刷新后的第二次无效?对不起,上面的代码中有一个错误。我已经修好了。它应该读Bullet.whereid,cookies[:bullets]。噢!嗯,这是常有的事。我很高兴能帮上忙。如果您觉得有帮助,我将非常感谢您的勾选/接受!身份证在里面。它是否需要一些东西来代替“?”语法中的id,cookies[:bullets]基本上意味着用变量cookies[:bullets]代替?在实际查询中。哦,好的,谢谢。请允许我问一下,为什么我对这个问题的第二次编辑第一次有效,但在刷新后的第二次无效?对不起,上面的代码中有一个错误。我已经修好了。它应该读Bullet.whereid,cookies[:bullets]。噢!嗯,这是常有的事。我很高兴能帮上忙。如果您觉得有帮助,我将非常感谢您的勾选/接受!