Sinatra 无法从帮助文件设置 cookie

Sinatra unable to set cookies from helper file

我的 sinatra 应用程序中有一个帮助程序文件,其中包含以下代码:

todo_sinatra_app/helpers/sessions_helper.rb

class SessionsHelper

  def self.sign_in(user)
    cookies[:remember_token] = { value: user.remember_token, expires: 20.years.from_now.utc }
    self.current_user = user
  end

...
end

当我尝试从我的 app.rb 文件调用 sign_in 方法时,它抛出一个错误,它不知道如何创建 cookies:

require 'sinatra'
require 'pg'
require 'sinatra/activerecord'
require 'sinatra/contrib'
require 'sinatra/cookies'
require './helpers/sessions_helper'
...

post '/sign_in' do
  user = User.find_by(email: params[:email])
  if user && user.authenticate(params[:password])
    SessionsHelper.sign_in(user)
    redirect '/'
  else
  ...
end

这是我的 gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    activemodel (5.2.0)
      activesupport (= 5.2.0)
    activerecord (5.2.0)
      activemodel (= 5.2.0)
      activesupport (= 5.2.0)
      arel (>= 9.0)
    activesupport (5.2.0)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 0.7, < 2)
      minitest (~> 5.1)
      tzinfo (~> 1.1)
    arel (9.0.0)
    backports (3.16.0)
    bcrypt (3.1.13)
    byebug (11.0.1)
    coderay (1.1.2)
    concurrent-ruby (1.1.5)
    daemons (1.3.1)
    diff-lcs (1.3)
    eventmachine (1.2.7)
    i18n (1.8.2)
      concurrent-ruby (~> 1.0)
    method_source (0.9.2)
    minitest (5.14.0)
    multi_json (1.14.1)
    mustermann (1.1.1)
      ruby2_keywords (~> 0.0.1)
    pg (1.2.2)
    pry (0.12.2)
      coderay (~> 1.1.0)
      method_source (~> 0.9.0)
    pry-byebug (3.7.0)
      byebug (~> 11.0)
      pry (~> 0.10)
    rack (2.1.2)
    rack-protection (2.0.8.1)
      rack
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rake (13.0.1)
    rspec (3.9.0)
      rspec-core (~> 3.9.0)
      rspec-expectations (~> 3.9.0)
      rspec-mocks (~> 3.9.0)
    rspec-core (3.9.1)
      rspec-support (~> 3.9.1)
    rspec-expectations (3.9.0)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.9.0)
    rspec-mocks (3.9.1)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.9.0)
    rspec-support (3.9.2)
    ruby2_keywords (0.0.2)
    sinatra (2.0.8.1)
      mustermann (~> 1.0)
      rack (~> 2.0)
      rack-protection (= 2.0.8.1)
      tilt (~> 2.0)
    sinatra-activerecord (2.0.14)
      activerecord (>= 3.2)
      sinatra (>= 1.0)
    sinatra-contrib (2.0.8.1)
      backports (>= 2.8.2)
      multi_json
      mustermann (~> 1.0)
      rack-protection (= 2.0.8.1)
      sinatra (= 2.0.8.1)
      tilt (~> 2.0)
    sinatra-flash (0.3.0)
      sinatra (>= 1.0.0)
    thin (1.7.2)
      daemons (~> 1.0, >= 1.0.9)
      eventmachine (~> 1.0, >= 1.0.4)
      rack (>= 1, < 3)
    thread_safe (0.3.6)
    tilt (2.0.10)
    tzinfo (1.2.6)
      thread_safe (~> 0.1)

PLATFORMS
  ruby

DEPENDENCIES
  activerecord (= 5.2)
  bcrypt
  minitest (= 5.14.0)
  pg
  pry-byebug
  rack-test
  rake
  rspec
  sinatra
  sinatra-activerecord
  sinatra-contrib
  sinatra-flash
  thin

BUNDLED WITH
   2.1.4

我已经尝试将 require 'sinatra/cookies' 放入辅助文件中,并确保捆绑了 gem 'sinatra-contrib'。当我直接在我的 app.rb 文件中设置 cookie 时,它​​会起作用。谁能建议我可以检查的其他任何东西或可能是什么问题?

当您 require 'sinatra' 某些神奇的事情发生时,将一堆东西带入作用域并从本质上将您的 app.rb 变成 Sinatra::Application 的实例。 cookies 方法只在这样的实例上定义——它不会自动出现在其他 类 上。

您可能想要做的是将您的助手变成一个真正的 Sinatra 风格的助手,方法是将它变成一个模块,然后使用 helpers 关键字加载它,这只会生成这些实例方法:

module SessionsHelper

  def sign_in(user)
    cookies[:remember_token] = { value: user.remember_token, expires:     20.years.from_now.utc }
    self.current_user = user
  end

...
end

在你的主文件中:

require './helpers/sessions_helper'
helpers SessionsHelper

...

post '/sign_in' do
  user = User.find_by(email: params[:email])
  if user && user.authenticate(params[:password])
    sign_in user
    redirect '/'
  else
  ...
end

您可能会喜欢read more about this in the README