Reputation: 1173
I am a new rails developer trying to get urls like:
www.twitter.com/theusername
Here's my route:
match "/:username" => "posts#index"
this works and routes my localhost:3000/theusername to localhost:3000/posts/
then I use:
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
Unfortunately, this brings up the error:
Called id for nil, which would mistakenly be 8 -- if you really wanted the id of nil, use object_id
Also, the web server brings up this (in case it helps):
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'
Upvotes: 0
Views: 2404
Reputation: 84114
Have you ever wondered why it is that inside your Post.search
block you are able to call methods such as fulltext
even though there is no such method on your controller ?
It's because inside that block self
has been changed (by instance_eval
). This is sometimes convenient, particularly when building DSLs such as sunspot's since the DSL methods are then callable without a receiver
However this means that within that block @user
refers to an instance variable of the sunspot object (which doesn't have one) and so it is nil. It looks like sunspot has some clever code to proxy methods to the original calling method (that's why calling params
) works, but that sort of trick doesn't work with instance variables.
The quick way around this is to do
@search = Post.search do |query|
query.fulltext params[:search]
query.with(:user, @user.id)
end
This makes the block a bog standard one with no changing of self
, at the price of a little verbosity.
Upvotes: 5
Reputation: 29291
That error you're getting is called a whiny nil. It's raised when you try to call the id
method on nil
.
It's probably related to your @user.id
. If @user
is nil, calling @user.id
will throw up a whiny nil error.
That's only in Rails 3, though. In Rails 4, whiny nils have been replaced by the regular NoMethodError: undefined method 'id' for nil:NilClass
.
Upvotes: 0
Reputation: 1694
You have to use to_param
method in your User model like this:
class User < ActiveRecord::Base
def to_param
username
end
end
Upvotes: 2