我的Ruby on Rails项目中有一个对象(工具)数据库。当我使用“rails dbconsole”和
时select * from tools;
它返回一整套工具对象。但是当我尝试查看以下页面时,它会给我一个错误。
页:
<!DOCTYPE html>
<html lang="en">
<%= stylesheet_link_tag "tools", :media => "all" %>
<body>
<%= @tools.each do |tool| %>
<%= link_to(tool(image_tag.image_url)) %>
<% end %>
</body>
</html>
错误:
undefined method `each' for nil:NilClass
当我更改代码以针对nil对象添加if语句时,页面正常工作(不显示任何工具)。
<% if @tools.nil? %>
<% else %>
<%= @tools.each do |tool| %>
<%= link_to(tool(image_tag.image_url)) %>
<% end %>
<% end %>
所以似乎@tools中没有任何值,但是当我在dbconsole中查看它时,那里有工具。我无法弄清楚这一点,过去几天我一直在谷歌上搜索答案,所以欢迎所有的想法!
编辑:添加了tools_controller.rb
class ToolsController < ApplicationController
before_filter :check_authentication
def check_authentication
unless session[:user_id]
session[:intended_action] = action_name
session[:intended_controller] = controller_name
redirect_to new_session_url
end
end
def new
@tool = Tool.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @tool }
end
end
def show
end
def index
@tools = Tool.all
end
# GET /tools/1/edit
def edit
@tool = Tool.find(params[:id])
end
# POST /tools
# POST /tools.json
def create
@tool = Tool.new(params[:tool])
respond_to do |format|
if @tool.save
format.html { redirect_to @tool, :notice => 'tool was successfully created.' }
format.json { render :json => @tool, :status => :created, :location => @tool }
else
format.html { render :action => "new" }
format.json { render :json => @tool.errors, :status => :unprocessable_entity }
end
end
end
end
答案 0 :(得分:2)
在@nbarraille建议的每个操作的before_filter中加载@tools
是一个坏主意,因为有很多(可能是大多数)操作,你肯定不需要完整的工具集(例如create
和destroy
)。第@tools = Tool.all
行会命中您的数据库,因此您应该尽量减少使用它的次数。
对于您在此处的情况,您只需更改show
操作即可使其生效:
def show
@tools = Tool.all
end
但请注意,通常show
操作用于显示单个资源(工具),而不是整个资源列表(通常在index
中完成行动)。看起来你偏离了正常的做事方式,有什么特别的原因吗?
答案 1 :(得分:1)
为了从您的视图中访问@tools
变量,您需要在控制器中声明它,如下所示:
@tools = Tool.all
如果您希望只能从一个页面访问它,只需在相应的方法中声明它。
以下是一个示例,假设您要为home/index
页面提供变量:
class HomeController < ApplicationController
def index
@tools = Tool.all
respond_to do |format|
format.html # index.html.erb
end
end
end
如果您希望在所有网页中都可以访问它,可以使用before_filter
的{{1}}方法进行声明。
以下是如何执行此操作:
ApplicationController