使用Rails 3,如何在模型中设置会话变量
session[:cannot_reason] = "no such item"
我想在我的用户模型中设置上述内容。现在我收到了这个错误:
undefined local variable or method `session' for #<User:0x00000102eb9c38>
想法?感谢
答案 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)
答案 2 :(得分:5)
会话对象在模型中不可见。将它作为参数传递给模型中的方法(恕我直言),或者在模型中定义一个返回所需内容的方法,然后将其存储在会话中(来自控制器)。
class User < ...
def item_status
return :no_such_item
end
end
在您的控制器中
session[:item_status] = current_user.item_status