/
session.rb
155 lines (146 loc) · 3.63 KB
/
session.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
require 'hanami/action/flash'
module Hanami
module Action
# Session API
#
# This module isn't included by default.
#
# @since 0.1.0
module Session
# The key that returns raw session from the Rack env
#
# @since 0.1.0
# @api private
SESSION_KEY = 'rack.session'.freeze
# The key that is used by flash to transport errors
#
# @since 0.3.0
# @api private
ERRORS_KEY = :__errors
# Add session to default exposures
#
# @since 0.4.4
# @api private
def self.included(action)
action.class_eval do
_expose :session, :flash
end
end
# Gets the session from the request and expose it as an Hash.
#
# @return [Hash] the HTTP session from the request
#
# @since 0.1.0
#
# @example
# require 'hanami/controller'
# require 'hanami/action/session'
#
# class Show
# include Hanami::Action
# include Hanami::Action::Session
#
# def call(params)
# # ...
#
# # get a value
# session[:user_id] # => '23'
#
# # set a value
# session[:foo] = 'bar'
#
# # remove a value
# session[:bax] = nil
# end
# end
def session
@_env[SESSION_KEY] ||= {}
end
# Read errors from flash or delegate to the superclass
#
# @return [Hanami::Validations::Errors] A collection of validation errors
#
# @since 0.3.0
#
# @see Hanami::Action::Validatable
# @see Hanami::Action::Session#flash
def errors
flash[ERRORS_KEY] || params.respond_to?(:errors) && params.errors
end
private
# Container useful to transport data with the HTTP session
#
# @return [Hanami::Action::Flash] a Flash instance
#
# @since 0.3.0
#
# @see Hanami::Action::Flash
def flash
@flash ||= Flash.new(session)
end
# In case of validations errors, preserve those informations after a
# redirect.
#
# @return [void]
#
# @since 0.3.0
# @api private
#
# @see Hanami::Action::Redirect#redirect_to
#
# @example
# require 'hanami/controller'
#
# module Comments
# class Index
# include Hanami::Action
# include Hanami::Action::Session
#
# expose :comments
#
# def call(params)
# @comments = CommentRepository.all
# end
# end
#
# class Create
# include Hanami::Action
# include Hanami::Action::Session
#
# params do
# param :text, type: String, presence: true
# end
#
# def call(params)
# comment = Comment.new(params)
# CommentRepository.create(comment) if params.valid?
#
# redirect_to '/comments'
# end
# end
# end
#
# # The validation errors caused by Comments::Create are available
# # **after the redirect** in the context of Comments::Index.
def redirect_to(*args)
if params.respond_to?(:valid?)
flash[ERRORS_KEY] = errors.to_a unless params.valid?
end
flash.keep!
super
end
# Finalize the response
#
# @return [void]
#
# @since 0.3.0
# @api private
#
# @see Hanami::Action#finish
def finish
super
flash.clear
end
end
end
end