AnA*_*ice 16 ruby-on-rails ruby-on-rails-3
使用Rails 3,如何在模型中设置会话变量
session[:cannot_reason] = "no such item"
Run Code Online (Sandbox Code Playgroud)
我想在我的用户模型中设置上面的内容.现在我收到此错误:
undefined local variable or method `session' for #<User:0x00000102eb9c38>
Run Code Online (Sandbox Code Playgroud)
想法?谢谢
and*_*wle 31
关于模型是否应该访问会话数据,存在一些不必要的货物结果.我认为这很愚蠢,因为会话实际上只是另一种形式的持久存储(尽管时间框架要短得多),而且在Rails中,让你的域对象也能够持久存在似乎没问题.
话虽这么说,不太干净的方法是将会话哈希作为参数传递给将对其进行操作的User方法:
class User < ...
def mymethod(session, count)
session[:count] = count
end
end
Run Code Online (Sandbox Code Playgroud)
在您的控制器中,您将执行以下操作:
def update
# ...
user.mymethod(session, count)
end
Run Code Online (Sandbox Code Playgroud)
想象一下mymethod,实现一些业务逻辑,这将session适当地修改哈希.您不必将session哈希传递回控制器,因为Ruby传递对象的引用(如哈希) - 对这些引用的对象进行破坏性修改.
一句忠告:在我看来,上面的例子很臭.这是因为UserActiveRecord模型(我假设)会持久存储到数据库中,并且我们正在添加使其也持久保存到会话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
Run Code Online (Sandbox Code Playgroud)
现在你的控制器看起来像这样:
def update
# ...
TemporaryCart.new(session).add_item
end
Run Code Online (Sandbox Code Playgroud)
如果你发现自己经常使用会话存储,那么这就更明显地揭示了会话访问代码的明显方法.还要注意我在会话哈希中命名数据(但没有显示此实现).我建议你这样做,这样你就不会在添加其他数据时踩到自己的脚趾.
总之,你不能.根据设计,模型无法访问cookie和会话.如果要从模型访问会话中的项目,则需要从控制器中明确传入它们.
会话对象在模型中不可见.将它作为参数传递给模型中的方法(恕我直言),或者在模型中定义一个返回所需内容的方法,然后将其存储在会话中(来自控制器).
class User < ...
def item_status
return :no_such_item
end
end
Run Code Online (Sandbox Code Playgroud)
在你的控制器中
session[:item_status] = current_user.item_status
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24516 次 |
| 最近记录: |