2012-05-02 11 views
1

私はcurrent_user.user_idにこのNoMethodErrorを取得しています。以下は私のユーザーモデルの表です。私はcurrent_user.user_idが存在するので、そのエラーの意味を知らない。何がこの問題を引き起こす可能性がありますか?私はここで失われています。私が覚えている限り、私はこのエラーに遭遇していませんでした。私はプロジェクトに新しいものを追加していました。私はユーザーモードに関係しない変更を行っていましたが。なぜNoMethodErrorの場合は、current_user.user_idが存在するのですか?無知で混乱しています。Ruby - レール - NoMethodError onユーザーモデル

エラー -

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 

答えて

2

current_userがnilを上げているので、あなたはこれを取得しているが。

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. はその後、

NOTE User.find(session[:user_id])@current_userを設定し続ける:それはユーザーを見つけることができない場合User.find()は、例外が発生します。 User.find_by_user_id()は例外を発生させずにnilを返します。確認し、あなたが望む動作を選択してください。

あなたの方法はOKです。つまり、session[:user_id]が設定されていない場合はnilになるはずです。あなたはあなたのコードでそれを捕らえる必要があります。 nilは虚偽なので、これはかなり簡単です。任意のRubyのコードでは:お使いのコントローラで

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 

returnを言うために(1)Rubyでは、あなたは、すべてのメソッドの最後の行を必要としないこと自動的に返され、(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メソッドをアプリケーションコントローラに移動することがあります。

あなたのコードと質問は、あなたがレールとRESTの本当の基本的な考え方のいくつかに精通していないことを反映しています。あなたが物事を行う "Rails Way"を学ぶなら、あなたは本当にあなたの開発をスピードアップします。あなたを軌道に乗せる素晴らしい、無料のリソースは、Michael HartlのRails 3 Tutorialでしょう。あなたはそれを通して仕事をしなければなりません、あなたが本当にうれしく思います、そして、あなたが終わったら、あなたは今どこにいるのかを先に知るでしょう。

+0

+1。アンドリューに感謝します!それは素晴らしい説明です。 –

3

エラーメッセージがcurrent_userに設定されていることを言っていますuser_idを呼び出すときにnil それ。あなたが含まれているコードに基づいてcurrent_usernilである理由を教えてもらえませんが、どのように/ current_userがどのようにユーザを割り当てているかを追跡することができれば、それがあなたの問題を見つけるでしょう。それはあなたのデータベースとは関係ありません。

+0

current_user関数で質問を更新しました。 –

+0

ありがとう!それを解決しました。それが問題でした。いくつかのajax呼び出しはアクティブなセッションを強制終了し、最終的に 'current_user.user_id'の' NoMethodError'を引き起こしていたCSRFトークンを送信していませんでした。 –

2

Userモデルが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"]}) 

それがfalseに評価され、その後のuser_idが呼び出されることはありません、代わりにそれはidがNULLである項目を照会しますnilをcurret_userがある場合。それがあなたのアプリケーションにふさわしい行動ならば、私はあなたに任せます。

そして、サイドノートとして、あなたの構文は、本当に私はこのように変更します。3.レールではありません。

@mylist = Item.select(:item_num).where(:id => (current_user && current_user.user_id), :item_status => ["New"]) 
+0

current_user関数で質問を更新しました。また、私は自分の要求に「警告:CSRFトークンの真正性を検証できません」というメッセージを表示しています。それはどういうわけかこれに関連していますか? –

+0

それはおそらく関連しているでしょう。それが起こるとき、私はセッションがクリアされ、ユーザーがログアウトしたと思う。これは通常、フォームでリモートコール(ajax)を使用し、レイアウトテンプレートに '<%= csrf_meta_tag%> 'を追加していない場合に発生します。 – DanneManne

+0

ありがとう!それを解決しました。それが問題でした。いくつかのajax呼び出しはアクティブなセッションを強制終了し、最終的に 'current_user.user_id'の' NoMethodError'を引き起こしていたCSRFトークンを送信していませんでした。 –

関連する問題