我是一名新的铁路开发人员,试图获取网址:
www.twitter.com/theusername
这是我的路线:
match "/:username" => "posts#index"
这可以工作并将我的localhost:3000 / theusername路由到localhost:3000 / posts /
然后我用:
def index
@user = User.find_by_username params[:username]
@search = Post.search do
fulltext params[:search]
with(:user, @user.id)
paginate(:page => params[:page] || 1, :per_page => 20)
end
end
不幸的是,这会带来错误:
如果你真的想要的话,被称为nil的id,这将错误地为8 nil的id,使用object_id
此外,Web服务器会提示(如果它有帮助):
Processing by PostsController#index as HTML
Parameters: {"username"=>"test"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."username" = 'test' LIMIT 1
Completed 500 Internal Server Error in 2ms
RuntimeError (Called id for nil, which would mistakenly be 8 -- if you really wanted the id of nil, use object_id):
app/controllers/posts_controller.rb:10:in `block in index'
app/controllers/posts_controller.rb:8:in `index'
答案 0 :(得分:5)
你有没有想过为什么在你的Post.search
块中你可以调用fulltext
之类的方法,即使你的控制器上没有这样的方法?
这是因为该块self
内部已被更改(instance_eval
)。这有时很方便,特别是在构建像太阳黑子这样的DSL时,因为DSL方法可以在没有接收器的情况下调用
然而,这意味着在该块@user
内引用了太阳黑子对象的实例变量(没有一个),因此它是零。看起来太阳黑子有一些聪明的代码来代理原始调用方法的方法(这就是为什么调用params
)有效,但这种技巧不适用于实例变量。
快速解决这个问题的方法是
@search = Post.search do |query|
query.fulltext params[:search]
query.with(:user, @user.id)
end
这使得该块成为一个标准的块,没有更改self
,但代价是有点冗长。
答案 1 :(得分:2)
您必须在用户模型中使用to_param
方法,如下所示:
class User < ActiveRecord::Base
def to_param
username
end
end
答案 2 :(得分:0)
您获得的错误称为 whiny nil 。当您尝试在id
上调用nil
方法时,会引发此问题。
这可能与您的@user.id
有关。如果@user
为零,则调用@user.id
会产生一个小的错误。
但这只是在Rails 3中。在Rails 4中,whiny nils已被常规NoMethodError: undefined method 'id' for nil:NilClass
取代。