1

NoMethodErrorcurrent_user.user_idに対してこれを取得しています。以下は私のユーザーモデルの表です。current_user.user_idが存在するため、そのエラーが何を意味するのかわかりません。この問題の原因は何ですか?私はここで迷子になっています。このエラーが発生しなかったことを覚えている限り、プロジェクトに新しいものを追加し続け、どこかで混乱しました。ユーザーモードに関係のない変更を加えていましたが。current_user.user_idが存在する場合、なぜNoMethodErrorが発生するのでしょうか。無知で混乱している。

エラー -

Started GET "/item/list" for 10.10.10.10 at 2012-05-01 23:19:19 -0400
Processing by Item#list as */*
Completed 500 Internal Server Error in 0ms

NoMethodError (undefined method `user_id' for nil:NilClass):
  app/controllers/Item_controller.rb:52:in `list'

ユーザーモデルテーブル-

mysql> explain users;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id    | varchar(255) | YES  |     | NULL    |                |
| name       | varchar(255) | YES  |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

current_user.user_idを使用するアイテムコントローラー-

    def list
    @mylist = Item.find(:all, :select => 'item_num', :conditions => { :id => current_user.user_id, :item_status => ["New"]} )
    respond_to do |format|
    format.html { render :partial => 'item_list'}
    format.js
    end
    return @mylist
    end


    def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end

    def debug
    render :text => current_user.user_id #prints correct user_id
    end
4

3 に答える 3

3

エラーメッセージは、それを呼び出そうとしたときににcurrent_user設定されていることを示しています。含まれているコードに基づいている理由はわかりませんが、ユーザーの割り当て方法と場所を追跡できれば、問題が見つかります。それはあなたのデータベースとは何の関係もありません。niluser_idcurrent_usernilcurrent_user

于 2012-05-02T03:41:27.073 に答える
2

問題は、ユーザーモデルがメソッドuser_idに応答しないことではないようですが、エラーメッセージによると、メソッドcurrent_userはnilを返し、nilはuser_idに応答しません。したがって、その理由はおそらく、ユーザーがログインしていなくてもこのアクションを呼び出すためです。

これを回避する1つの方法は、user_idを呼び出す前に、まずcurrent_userが何かを返すかどうかを確認することです。多分このように:

@mylist = Item.find(:all, :select => 'item_num', :conditions => { :id => (current_user && current_user.user_id), :item_status => ["New"]} )

curret_userがnilの場合、falseと評価され、user_idは呼び出されず、代わりにidがNULLのアイテムを照会します。それがあなたのアプリにとって適切な振る舞いであるなら、私はあなたに任せます。

ちなみに、構文は実際にはRails3ではありません。次のように変更します。

@mylist = Item.select(:item_num).where(:id => (current_user && current_user.user_id), :item_status => ["New"])
于 2012-05-02T03:42:08.493 に答える
2

current_userゼロになっているので、これを取得しています。現在のユーザー関数は、思ったとおりに機能しません。見てみましょう。

def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
end

したがって、これは次の順序で実行されます。

  1. ある場合はsession[:user_id]、続行します| またはnilを返します

  2. 次に、が設定されている場合は、 |@current_userを返します。@current_userまたは続行します

  3. 次に、に設定@current_userしますUser.find(session[:user_id])

注:User.find()ユーザーが見つからない場合は例外が発生します。例外を発生させずUser.find_by_user_id()に戻るだけです。nil必ず、必要な動作を選択してください。

あなたの方法は大丈夫です、それはあなたが設定されていないときはnilいつでもあなたが得るつもりであることを意味します。session[:user_id]コードでそれをキャッチする必要があります。偽物なのでnil、これはかなり簡単です。ルビーコードの場合:

any_method if current_user

コントローラでは、次のことを行う必要があります。

def list
  if current_user
    @mylist = Item.find(:all, :select => 'item_num', :conditions => { :id => current_user.user_id, :item_status => ["New"]} )
    respond_to do |format|
      format.html { render :partial => 'item_list'}
      format.js
    end
  else
    redirect_to login_path, :notice => "You must be logged in to continue."
  end
end

(1)Rubyでは言う必要はありません。returnすべてのメソッドの最後の行が自動的に返されます。(2)リダイレクトまたはレンダリングするとRailsコントローラーメソッドが終了し、返されません。

これをよりクリーンにするために、おそらくbefore_filterが必要だと思います。あなたのコントローラーでこのような何かがトリックをするはずです:

before_filter :require_login

def require_login
  redirect_to login_path, :message => 'You must be logged in to view this page.' unless current_user
end

次に、まだログインしていない場合は、すべてのメソッドがそのユーザーをログインにリダイレクトします。:onlyまたは:exceptオプションを使用して、このフィルターを使用する特定のメソッドのみを指定することもできます。

アプリ全体でこれを使用する可能性が高いため、メソッドcurrent_userrequire_loginメソッドをアプリケーションコントローラーに移動する場合があります。

最後にもう1つ、コードと質問は、レールとRESTの実際の基本的な考え方のいくつかに精通していないことを反映しています。物事を行うための「レールウェイ」を学べば、開発を本当にスピードアップできます。あなたを軌道に乗せるための素晴らしい無料のリソースは、MichaelHartlのRails3チュートリアルです。あなたはそれをやり遂げるべきです、あなたはあなたがしたことを本当にうれしく思います、そしてあなたが終わったときあなたはあなたが今いるところよりずっと先を行くでしょう。

于 2012-05-02T04:16:33.797 に答える