在模型中设置会话变量

时间:2011-08-27 19:27:24

标签: ruby-on-rails ruby-on-rails-3

使用Rails 3,如何在模型中设置会话变量

session[:cannot_reason] = "no such item"

我想在我的用户模型中设置上述内容。现在我收到了这个错误:

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

想法?感谢

3 个答案:

答案 0 :(得分:31)

关于模型是否应该访问会话数据,存在一些不必要的货物结果。我认为这很愚蠢,因为会话实际上只是另一种形式的持久存储(尽管时间框架要短得多),而且在Rails中,让你的域对象也能够自行保存似乎没问题。

话虽如此,不太干净的方法是将会话哈希作为参数传递给将对其进行操作的User方法:

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

在你的控制器中,你会做类似的事情:

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

想象mymethod正在实现一些业务逻辑,这将适当地修改session哈希。您不必将session哈希传递回控制器,因为Ruby传递对象的引用(如哈希) - 对这些引用的对象进行破坏性修改。

一条忠告:在我看来,上面的例子很臭。这是因为User是一个ActiveRecord模型(我假设)它会持久存储到数据库中,并且我们正在添加使其也持久保存到会话cookie的行为。对我来说,这违反了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

如果您发现自己经常使用会话存储,那么这会更明显地揭示会话访问代码的明显方法。还要注意我在会话哈希中命名数据(但没有显示此实现)。我建议你这样做,这样你就不会在添加其他数据时踩到自己的脚趾。

答案 1 :(得分:7)

总之,你不能。根据设计,模型无法访问cookie和会话。如果要从模型中访问会话中的项目,则需要从控制器中明确传入它们。

答案 2 :(得分:5)

会话对象在模型中不可见。将它作为参数传递给模型中的方法(恕我直言),或者在模型中定义一个返回所需内容的方法,然后将其存储在会话中(来自控制器)。

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

在您的控制器中

session[:item_status] = current_user.item_status