Rails读取Cookie会返回字符串而不是对象

时间:2018-07-20 10:41:51

标签: ruby-on-rails cookies activerecord

我有两个控制器。我的Sellers controller设置并读取Cookie很好。 在我的Titles Controller中,尝试读取Cookie会导致返回字符串,而不是对象。 因此,cookies[:user].idSellers Controller中有效,但在Titles Controller中返回错误:undefined method shop_name'代表“#”:字符串`

这是Sellers Controller的代码:

class SellersController < ApplicationController
  before_action :set_cookies

  def show
    @seller = Seller.find(params[:id])
    @user = cookies[:user]
    @shop = cookies[:shop]
    @listings = Listing.where(shop: @shop).paginate(page: params[:page])
  end

  private
    def set_cookies
      cookies[:user] = current_user
      cookies[:seller] = Seller.find(params[:id])
      cookies[:shop] = Shop.where(seller: cookies[:seller]).first
    end
end

这是我的Titles Controller:

class TitlesController < ApplicationController
  before_action :find_data

  def index
    @titles = Title.last
  end

  private
    def find_data
      @shop = cookies[:shop]
      @seller = cookies[:seller]
      @user = cookies[:user]
    end
end

检查调试器中的变量将得到以下输出:

@shop
=> "#<Shop:0x00007f433f785dc8>"
>> 
@shop.inspect
=> "\"#<Shop:0x00007f433f785dc8>\""
>> 
cookies[:shop].class
=> String

我在这里做错什么吗? 谢谢!

1 个答案:

答案 0 :(得分:2)

Cookie是基于字符串的。因此,将非字符串值存储到cookie时需要在设置值时进行序列化,然后在读取值时进行反序列化。参见cookies docs here

但是,通常,您不对数据库记录进行序列化,因为一旦通过反序列化获得了ActiveRecord对象,它可能已经过时(不是数据库中的实际值最新)。这就是为什么我建议您在下面做一些事情的原因。

app / controllers / sellers_controller.rb:

class SellersController < ApplicationController
  before_action :set_seller, only: [:show]
  before_action :set_seller_first_shop, only: [:show]
  before_action :set_cookies, only: [:show]

  def show
    @listings = Listing.where(shop: @shop).paginate(page: params[:page])
  end

  private

    def set_seller
      @seller = Seller.find(params[:id])
    end

    def set_seller_first_shop
      @shop = @seller.shops.first
    end

    def set_cookies
      cookies.signed[:user_id] = current_user.id
      cookies.signed[:seller_id] = @seller.id
      cookies.signed[:shop_id] = @shop.id
    end
end

app / controllers / titles_controller.rb

class TitlesController < ApplicationController
  before_action :set_from_cookies, only: [:index]

  def index
    @titles = Title.last
  end

  private

    def set_from_cookies
      @shop = Shop.find(cookies.signed[:shop_id])
      @seller = Seller.find(cookies.signed[:seller_id])
      @user = User.find(cookies.signed[:user_id])
    end
end