2
2
3
3
class SessionDatesController < ApplicationController
4
4
before_action :set_session
5
+ before_action :set_draft_session_dates
5
6
6
7
def show
7
- @session . session_dates . build if @session . session_dates . empty?
8
- end
9
-
10
- def update
11
- @session . assign_attributes ( remove_invalid_dates ( session_params ) )
12
- @session . set_notification_dates
8
+ initialize_draft_from_session
13
9
14
- render :show , status : :unprocessable_content and return if @session . invalid?
15
-
16
- @session . save!
17
-
18
- # If deleting dates, they don't disappear from `session.dates` until
19
- # the model has been saved due to how `accepts_nested_attributes_for`
20
- # works.
21
- if any_destroyed?
22
- @session . session_dates . reload
23
- @session . set_notification_dates
24
- @session . save!
10
+ if params [ :add_another ] ||
11
+ @draft_session_dates . session_dates_attributes . empty?
12
+ add_blank_session_date
25
13
end
14
+ end
26
15
27
- StatusUpdaterJob . perform_later ( session : @session )
16
+ def update
17
+ @draft_session_dates . session_dates_attributes =
18
+ fetch_draft_session_dates_from_form
28
19
29
- if params . include? ( :add_another )
30
- @session . session_dates . build
20
+ if params [ :delete_date ]
21
+ delete_session_date ( form_index_to_attr_index ( params [ :delete_date ] ) )
22
+ return render_with_error if @draft_session_dates . errors . any?
23
+ render :show
24
+ elsif params [ :add_another ]
25
+ add_blank_session_date
31
26
render :show
32
27
else
33
- redirect_to (
34
- if any_destroyed?
35
- session_dates_path ( @session )
36
- else
37
- edit_session_path ( @session )
38
- end
39
- )
28
+ unless @draft_session_dates . save ( context : :continue )
29
+ return render_with_error
30
+ end
31
+ apply_changes_and_redirect
40
32
end
41
33
end
42
34
@@ -46,41 +38,121 @@ def set_session
46
38
@session = policy_scope ( Session ) . find_by! ( slug : params [ :session_slug ] )
47
39
end
48
40
49
- def session_params
50
- params . expect (
51
- session : {
52
- session_dates_attributes : [ %i[ id value _destroy ] ]
53
- }
41
+ def set_draft_session_dates
42
+ @draft_session_dates =
43
+ DraftSessionDates . new (
44
+ request_session : session ,
45
+ current_user : current_user ,
46
+ session : @session ,
47
+ wizard_step : :dates
48
+ )
49
+ end
50
+
51
+ def draft_session_dates_params
52
+ params
53
+ . fetch ( :draft_session_dates , { } )
54
+ . permit (
55
+ session_dates_attributes : [
56
+ :id ,
57
+ :value ,
58
+ :_destroy ,
59
+ "value(1i)" ,
60
+ "value(2i)" ,
61
+ "value(3i)"
62
+ ]
63
+ )
64
+ . merge ( wizard_step : :dates )
65
+ end
66
+
67
+ def initialize_draft_from_session
68
+ attributes = { }
69
+
70
+ @session
71
+ . session_dates
72
+ . order ( :value )
73
+ . each_with_index do |session_date , index |
74
+ attributes [ index ] = {
75
+ "id" => session_date . id . to_s ,
76
+ "value" => session_date . value
77
+ }
78
+ end
79
+
80
+ @draft_session_dates . session_dates_attributes = attributes
81
+ @draft_session_dates . save! ( context : :initialize )
82
+ end
83
+
84
+ def add_blank_session_date
85
+ current_attrs = @draft_session_dates . session_dates_attributes
86
+ next_index = ( current_attrs . keys . map ( &:to_i ) . max || -1 ) + 1
87
+ current_attrs [ next_index ] = { "value" => nil }
88
+ @draft_session_dates . session_dates_attributes = current_attrs
89
+ end
90
+
91
+ def render_with_error
92
+ render :show , status : :unprocessable_content
93
+ end
94
+
95
+ def apply_changes_and_redirect
96
+ @draft_session_dates . write_to! ( @session )
97
+ session . delete ( @draft_session_dates . request_session_key )
98
+ StatusUpdaterJob . perform_later ( session : @session )
99
+ redirect_to edit_session_path ( @session )
100
+ rescue ActiveRecord ::RecordInvalid => e
101
+ @draft_session_dates . errors . add (
102
+ :base ,
103
+ "Failed to save session dates: #{ e . message } "
54
104
)
105
+ render_with_error
55
106
end
56
107
57
- def any_destroyed?
58
- session_params [ :session_dates_attributes ] . values . any? do
59
- _1 [ :_destroy ] . present?
108
+ def form_index_to_attr_index ( form_index )
109
+ current_attrs = @draft_session_dates . session_dates_attributes
110
+ corresponding_form_index = -1
111
+ current_attrs . each do |real_index , attrs |
112
+ corresponding_form_index += 1 unless attrs [ "_destroy" ] == "true"
113
+
114
+ return real_index if corresponding_form_index . to_s == form_index
60
115
end
116
+
117
+ (
118
+ form_index . to_i - corresponding_form_index . to_i + current_attrs . length
119
+ ) . to_s
61
120
end
62
121
63
- def remove_invalid_dates ( obj , key : "session_dates_attributes" )
64
- return obj if obj [ key ] . blank?
65
-
66
- obj [ key ] = obj [ key ] . transform_values do |value |
67
- if value . key? ( "value(1i)" ) && value . key? ( "value(2i)" ) &&
68
- value . key? ( "value(3i)" )
69
- begin
70
- Date . new (
71
- value [ "value(1i)" ] . to_i ,
72
- value [ "value(2i)" ] . to_i ,
73
- value [ "value(3i)" ] . to_i
74
- )
75
- value
76
- rescue StandardError
77
- { }
78
- end
79
- else
80
- value
81
- end
122
+ def fetch_draft_session_dates_from_form
123
+ current_attrs = @draft_session_dates . session_dates_attributes
124
+
125
+ form_params = draft_session_dates_params [ :session_dates_attributes ] || { }
126
+
127
+ merged_attrs = { }
128
+
129
+ current_attrs . each do |index , attrs |
130
+ merged_attrs [ index ] = attrs if attrs [ "_destroy" ] == "true"
82
131
end
83
132
84
- obj
133
+ form_params . each do |form_index , form_attrs |
134
+ attr_index = form_index_to_attr_index ( form_index )
135
+ merged_attrs [ attr_index ] = form_attrs
136
+ end
137
+
138
+ merged_attrs
139
+ end
140
+
141
+ def delete_session_date ( index )
142
+ current_attrs = @draft_session_dates . session_dates_attributes
143
+
144
+ if current_attrs [ index ]
145
+ if @draft_session_dates . non_destroyed_session_dates_count <= 1
146
+ @draft_session_dates . errors . add (
147
+ :base ,
148
+ "You cannot delete the last session date. A session must have at least one date."
149
+ )
150
+ return
151
+ end
152
+
153
+ current_attrs [ index ] [ "_destroy" ] = "true"
154
+ @draft_session_dates . session_dates_attributes = current_attrs
155
+ @draft_session_dates . save! ( context : :update )
156
+ end
85
157
end
86
158
end
0 commit comments