2011-08-27 3 views
15
でのRails 3で

をセッション変数を設定すると、あなたがモデルにモデル

session[:cannot_reason] = "no such item" 

をセッション変数を設定することができますどのように私は私のユーザモデルでは上記を設定したいと思います。今すぐこのエラーが発生します:

undefined local variable or method `session' for #<User:0x00000102eb9c38> 

アイデア?ありがとう

答えて

30

class User < ... 
    def item_status 
    return :no_such_item 
    end 
end 

は、モデルは、セッションデータへのアクセス権を持っているかどうかについて、いくつかの不要な貨物cultingあります。私はこれが愚かだと思います。なぜなら、セッションは永続的なストレージのもう一つの形態なのです(ただし、はるかに短い時間枠ではありますが)。また、Railsでは、ドメインオブジェクトも永続化することができます。その後、お使いのコントローラで

class User < ... 
    def mymethod(session, count) 
    session[:count] = count 
    end 
end 

、あなたがなります言われて、それを行うには非常にきれいではない方法は、それを操作するユーザーのメソッドにパラメータとしてセッションハッシュを渡すだろうと

ような何か:mymethodは、いくつかのビジネス・ロジックを実装していることを想像

def update 
    # ... 
    user.mymethod(session, count) 
end 

を、これは適切sessionハッシュを変更します。ハッシュをコントローラに渡す必要はありません。これは、Rubyが(Hashのような)オブジェクトへの参照を渡すためです。変更はそれらの参照オブジェクトに対して破壊的に行われます。

アドバイスの単語:私の意見では、上記の例は臭いです。これは、Userが(私が推測している)ActiveRecordモデルでデータベースに残っており、セッションクッキーにも永続させるような動作を追加しているからです。私にとっては、これはSRPに違反し、避けるべきです。

これを実装する方法は、その存在の理由をカプセル化した別のドメインオブジェクトにセッションストレージロジックを抽出することです。たとえば、countは単なる「カウント」ではなく、ユーザーの一時的なカートのアイテム数の合計です。

class TemporaryCart 
    def initialize(session) 
    @session = session 
    end 

    def add_item 
    # ... other item adding logic 
    @session[:temporary_cart][:num_items] += 1 
    end 
end 

今、あなたのコントローラは次のようになります。

def update 
    # ... 
    TemporaryCart.new(session).add_item 
end 

これは、はるかに暴露のであり、あなたがセッションストレージをたくさん使って自分自身を見つけるかどうかを抽象化セッションのアクセスコードへの明白な方法のためにドアを開けます。また、セッションハッシュのデータを名前空間に入れたことに気付く(ただし、この実装は表示されませんでした)。私はこれを行うことをお勧めしますので、他のデータを追加する際に足を踏み入れないでください。

7

要するに、できません。設計上、モデルはクッキーとセッションにアクセスできません。モデルからセッション内の項目にアクセスする場合は、コントローラから明示的に渡す必要があります。

+2

どのように渡しますか?例を使ったマインド編集?ありがとう – AnApprentice

+4

モデルセッションを使用するべきではありません、これは非常に多くのレベルで間違っています –

5

セッションオブジェクトはモデルでは表示されません。モデルのメソッドにパラメータとして渡すか(IMHO悪い)、モデル内で必要なものを返すメソッドを定義し、それをコントローラのセッションに保存します。お使いのコントローラ

session[:item_status] = current_user.item_status