0

私は次のような URL を取得しようとしている新しい Rails 開発者です。

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'
4

3 に答える 3

5

controller にそのようなメソッドがないのに、Post.searchブロック内で などのメソッドを呼び出すことができるのはなぜだろうと思ったことはありませんか?fulltext

それは、そのブロックの内部がself(によってinstance_eval) 変更されたためです。これは、特に太陽黒点などの DSL を構築する場合に便利な場合があります。これは、DSL メソッドがレシーバーなしで呼び出せるためです。

ただし、これは、そのブロック内で@user太陽黒点オブジェクトのインスタンス変数 (存在しない) を参照するため、nil であることを意味します。sunspot には、メソッドを元の呼び出しメソッドにプロキシするための巧妙なコードがあるように見えますが (そのため、 の呼び出しparams) は機能しますが、そのようなトリックはインスタンス変数では機能しません。

これを回避する簡単な方法は、

@search = Post.search do |query|
    query.fulltext params[:search]
    query.with(:user, @user.id)
end

これにより、このブロックselfは、少し冗長になるという代償を払って、変更のない標準的な標準ブロックになります。

于 2013-06-27T18:01:42.983 に答える
2

to_param次のように User モデルでメソッドを使用する必要があります。

class User < ActiveRecord::Base
  def to_param 
    username
  end
end
于 2013-06-27T16:55:42.810 に答える