2013-12-15 11 views
5

私はCプログラミングのバックグラウンドを持っており、サイドプロジェクトのRuby/Railsを学んでいます。現在、私は変数の有効範囲の仕組みを理解するのに苦労しています。ここに私が打つ問題の例があります。私はUserとProductモデルを持っています。製品DBにはさまざまな製品が格納されており、フィールドの1つはUserテーブルに格納されているuseridと一致するuseridフィールドです。ユーザーがログインすると、ユーザーの名前、電子メールなどが表示されます(これは@ current_userに格納されます)。次に、ユーザーが所有する別の製品を表示するためのリンクがあります。私は、ユーザーに次のコードを経由して、これを行う/このようなshow.html.erb: ... Railsの別のコントローラで1つのコントローラ変数にアクセス

名: <% = @ current_user.name%>

... <% =のlink_to "products"、products_path、id: "products"%>

これまでのところとても良いです。 「Products」リンクをクリックするとproducts/index.html.erbに移動し、次のコードが実行されます(この表示をフィルタリングして、@ current_user.useridが所有する製品のみを表示します。私は、WHERE句は、すべての製品は、私が欲しいものではありませんどの表示AR「場合」を削除した場合@current_userが。私は信じてnilに評価されるコードは、次のことは私に、ランタイムエラーが発生します。任意のヒントに感謝されるだろう。

<tbody> 
<% @products.each do |product| %> 
    <tr> 
    <td><%= product.userid if product.userid == @current_user.userid %></td> 
    <td><%= product.productName if product.userid == @current_user.userid %></td> 
    <td><%= product.productLink if product.userid == @current_user.userid %></td> 

おかげで、

+1

私は貴重な宝石を調べることをお勧めします。これがなければ、ユーザをフェッチして結果をメモするアプリケーションヘルパーメソッド 'current_user'を追加します。 Deviseは、ほとんどのRailsプロジェクトで使用されている非常に人気のある宝石です。しかし、あなたが好きなら私は手動の方法で答えを作り出すことができます。 –

答えて

10

私はこれをコメントにしようとしていましたが、回答に値すると思います。レールだけでなくインターネット全体について理解することは、のHTTPはステートレスです。つまり、コントローラではユーザの情報を取得し、データベースからすべてのものを含むWebページを作成し、それらに送信します。それから、彼らはページ上で何かをして、別のページ以上のデータを要求します。あなたのレールアプリは、「ああ、ハァッ!あなたは誰ですか?すてきな情報で埋め尽くされた変数はすべてなくなったからです。あなたのアプリがリクエストを受け取るたびに、それは使用しているコントローラのまったく新しいインスタンスを作成し、その後、それの中のすべてと一緒にそれを取り除きます。これは重要なことです。なぜなら、何千人、何百万人もの人々が現在、あなたの土曜日にどこでプレーしているのかを把握しようと、究極のフリスビーリーグのウェブサイトにログインしているからです。そして、あなたは正しい人に正しい情報を与えたい、あなたが最後に情報を送った人があなたに新しい情報を求めているのと同じ人物であると仮定することはできません。

sessionを使用する必要があります。一部の情報は、ページを送信するたびにクライアントブラウザに渡され、ブラウザはリクエストごとに返信します。セッションに十分な情報を入れて、応答を受け取ったときにサーバーから必要なものを再構築するために使用することができます。私はこれを本当のシンプルなものにして、より重要な情報を得ることができるRails Security Guideにあなたを紹介します。その後、

@current_user = User.find(session[:user_id]) 

そして:あなたがセッションにこのようユーザーIDを追加することができます

session[:user_id] = @current_user.id 

をしてから、この方法でそれを取り戻す実は、私はちょうど彼らの例を使用しますユーザーモデル(この場合)を使用して、必要な特定の情報をデータベースから取得します。それはとても素敵ですので、ここでのRailsへの別のリンクが導くだ、私は二回、それをリンクしています:http://guides.rubyonrails.org/security.html#what-are-sessions-questionmark

あなたはdeviseinstructions hereのような宝石を使用することができますが、それは全くハイジャックを警告されるパスワードを必要とする何かをしている場合あなたのユーザモデル、あなたのセッションコントローラ、いくつかのビュー、基本的にログインとアイデンティティに関連するすべてのもの。カスタマイズするのは簡単ではありませんが、このようなものや事柄は非常に複雑になり、実装が非常に簡単になります。ユーザー名やパスワードが不要で、あなたが本当に簡単なことをしているのなら、特別な宝石はスキップして、セッションを自分で使用してください。

0

あなたは、ユーザーがログインした後だけでなく、それぞれの要求に@current_userを初期化する必要があります。コントローラのインスタンス変数が要求間で維持されません。

これを行う一般的な方法は次のとおりです。

  1. セッションにユーザーIDを格納します。
  2. ApplicationControllerに「before」フィルタを作成して、セッションからユーザーIDを取得し、インスタンス変数を初期化します。
0

あるアクションで設定されたインスタンス変数に別のアクションでアクセスすることはできません。前述のとおり、セッションハッシュにuser_idを格納する必要があります。セッションハッシュにUSER_ID:セッションキーへのuser_idを割り当てる

#in SessionsController(for example) 

def create 
    user = User.find_by(email: params[:session][:email].downcase) 
    if user && user.authenticate # logic for authentication 
    session[:user_id] = user.id 
    redirect_to root_path, notice: "Successful sign in." 
    else 
    flash.now[:error] = "Invalid email/password combination" 
    render :new 
    end 
end 

をメモ:ユーザーsign_inを扱うコントローラでは、このような何かを行う必要があります。さて、application_helperまたはそれはすべてのビューにアクセス可能なようにsessions_helper current_userを定義します。

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

今、特定のユーザーの製品のすべてを反復処理するために:限り、あなたはhas_many :products関連を持っているよう

<tbody> 
<% current_user.products.each do |product| %> 
    <tr> 
    <td><%= product.userid %></td> 
    <td><%= product.product_name %></td> 
    <td><%= product.product_link %></td> 

ユーザーと商品のモデルがbelongs_to :userの場合、上記のようにuser.productsを実行するだけで、すべてのユーザーの製品に電話をかけることができます。製品のメソッド/属性に 'snake_case'を使用したことにも注意してください。メソッド名と変数にsnake_caseを使用するのはRubyの規約です。 productNameとproductLinkという列に名前を付けた場合は、 'snake_case'を使用できるように名前を変更する必要があります。 Rubyでは、CamelCaseはClassおよびModuleNamesに使用されます。

希望に役立ちます!

+0

すべての有益なコメントをいただきありがとうございました。私はこのスレッドでいくつか新しいことを学びました。このウェブ開発の世界は私が慣れ親しんだものとはまったく異なります!私はこのスレッドを読んだ後に私が望むことをすることができました。私は数回立ち往生したが、私の周りの方法をGoogleで見つけた。あまりにも多くのレールについては、黒い魔法のように思える。 – user3079275

+0

私のコメントが助けになったことを知ってよかった!あなたはRailsがたくさんの黒い魔法をやっていると思うのは正しいです。これは巨大なフレームワークであり、利便性のために複雑さを払っています。あなたがその慣習に固執すれば、より生産的になることがわかります。その間のドキュメントをお勧めします。 Rubyのメタプログラミングのトリック、そしてRailsの公開APIで、最終的にソースに潜入して、それがどのように機能するかを知ることができます。 – Gjaldon

関連する問題