session 出现在教材https://fullstack.xinshengdaxue.com/posts/416
加入购物车代码

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

 # ...略


+  helper_method :current_cart

+  def current_cart
+    @current_cart ||= find_cart
+  end

+  private

+  def find_cart
+    cart = Cart.find_by(id: session[:cart_id])
+    if cart.blank?
+      cart = Cart.create
+    end
+    session[:cart_id] = cart.id
+    return cart
+  end
end

session是用户ID的一个载体。在购物商店的例子中,每个人进入商店的时候,都会领到一张电子卡就是session。只要查询session上的card_id就可以这台购物车里面有多少商品和每种商品的数量。 如果发现你的车丢了,if cart.blank? = true,会通过cart=Cart.create重新发一辆车并且分配一个新的购物车号码 session[:cart_id]=cart.id.每个用户当前的购物车current_cart就是通过这样的方式存取的

session的工作原理

当程序需要为某个客户端application的请求request建立一个 session 的时候,服务器首先检查这个客户端的请求中是否已经包含了一個 session辨识码 - 称为 session id。如果已经包含一个 session id,则说明以前已经为此客户端创建过 session,服务器就按照session id 把这个 session 检索出來使用。如果客户端请求不包含 session id,则为此客户端创建一個 session 并且生成一个与此 session 相关联的 session id。session id 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串。这个 session id 将在本次响应respone中返回給客戶端保存。保存这个 session id 的方式可以采用 cookie,这样在交互过程中浏览器可以自动地按照规则把这个标识发給服务器。

session 存在的原因

session 之所以会存在,是因为 HTTP 为 stateless无状态的设计,Server 和 Client 不会一直保持连线状态,也不会有双方状态的即时更新。所以,Server 并不知道 Client 的状态(像是否已经登入)。因此,后来的网站开发者,采用 Session这样的设计來解決这个问题。

card_id的储存需要载体,所以代码不能写成cart = Cart.find_by(id: cart.id), 要写成

session[:card_id] = cart_id
cart = Cart.find_by(id: session[:cart_id])

Rails,session 默认存储于 cookie 中,可通过 config/initializers/session_store.rb 查看。

session 以 cookie 的方式存储的加密还是会依赖于 secret_key_base 参数的值,所以 secret_key_base 千万不能泄漏。

指定:session[:cart_id] = cart.id
读取:session[:cart_id]
刪除:session[:cart_id] = nil
清空:reset_session

参考资料:
https://en.wikipedia.org/wiki/Session_computer_science)(
https://rocodev.gitbooks.io/rails-102/content/chapter2-rails/cookies-and-session.html
https://ihower.tw/rails/actioncontroller.html#sec8
https://en.wikipedia.org/wiki/Session_ID
http://www.tuicool.com/articles/f6F7by
http://sylviablog.logdown.com/posts/1786808