• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codebar / planner / 30624278172

31 Jul 2026 10:39AM UTC coverage: 93.048%. First build
30624278172

Pull #2770

github

web-flow
Merge 3d5e0a04a into 106b7b19b
Pull Request #2770: style(rubocop): resolve three next quick-win todo entries

11 of 27 new or added lines in 3 files covered. (40.74%)

3801 of 4085 relevant lines covered (93.05%)

42.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.09
/app/controllers/admin/workshops_controller.rb
1
class Admin::WorkshopsController < Admin::ApplicationController
6✔
2
  include Admin::WorkshopConcerns
6✔
3

4
  before_action :set_workshop_by_id, only: %i[show edit destroy update]
6✔
5
  before_action :set_and_decorate_workshop, only: %i[attendees_checklist attendees_emails send_invites changes]
6✔
6
  before_action :set_workshop, only: %i[sponsor destroy_sponsor host destroy_host]
6✔
7
  before_action :set_sponsor, only: %i[sponsor host]
6✔
8

9
  WORKSHOP_DELETION_TIME_FRAME_SINCE_CREATION = 4.hours
6✔
10

11
  def index
6✔
12
    @chapter = Chapter.find(chapter_id)
1✔
13
    authorize @chapter
1✔
14
    @workshops = @chapter.workshops.includes(:sponsors)
1✔
15
  end
16

17
  def new
6✔
18
    @workshop = Workshop.new
6✔
19
    authorize @workshop
6✔
20
  end
21

22
  def create
6✔
23
    @workshop = Workshop.new(workshop_params)
7✔
24
    authorize(@workshop)
7✔
25

26
    if workshop_type_valid? && @workshop.save
7✔
27
      grant_organiser_access(@workshop.chapter.organisers.pluck(:id))
3✔
28
      assign_host(host_id)
3✔
29

30
      redirect_to admin_workshop_path(@workshop), notice: I18n.t('admin.messages.workshop.created')
3✔
31
    else
32
      flash[:warning] = @workshop.errors.full_messages
4✔
33
      render 'new'
4✔
34
    end
35
  end
36

37
  def edit
6✔
38
    authorize @workshop
1✔
39
  end
40

41
  def show
6✔
42
    authorize @workshop
30✔
43
    @workshop = WorkshopPresenter.decorate(@workshop)
30✔
44
    if request.format.csv?
30✔
45
      csv_to_render = params[:type].eql?('labels') ? @workshop.attendees_csv : @workshop.pairing_csv
2✔
46
      return render plain: csv_to_render
2✔
47
    end
48

49
    set_admin_workshop_data
28✔
50
  end
51

52
  def update
6✔
53
    authorize @workshop
1✔
54

55
    @workshop.assign_attributes(workshop_params)
1✔
56

57
    if workshop_type_valid? && @workshop.valid?
1✔
58
      @workshop.save
1✔
59
      update_workshop_details
1✔
60

61
      redirect_to admin_workshop_path(@workshop), notice: I18n.t('admin.messages.workshop.updated')
1✔
62
    else
63
      flash[:warning] = @workshop.errors.full_messages
×
64
      render 'edit'
×
65
    end
66
  end
67

68
  def send_invites; end
6✔
69

70
  def attendees_checklist
6✔
71
    return render plain: @workshop.attendees_checklist if request.format.text?
2✔
72

73
    redirect_to admin_workshop_path(@workshop),
1✔
74
                notice: I18n.t('messages.invalid_format', invalid_format: request.format)
75
  end
76

77
  def attendees_emails
6✔
78
    return render plain: @workshop.attendees_emails if request.format.text?
1✔
79

80
    redirect_to admin_workshop_path(@workshop)
×
81
  end
82

83
  def invite
6✔
84
    set_workshop
2✔
85
    authorize @workshop
2✔
86
    audience = params[:for]
2✔
87

88
    if @workshop.virtual?
2✔
89
      InvitationManager.new.send_virtual_workshop_emails(@workshop, audience, current_user.id)
1✔
90
    else
91
      InvitationManager.new.send_workshop_emails(@workshop, audience, current_user.id)
1✔
92
    end
93

94
    redirect_to admin_workshop_path(@workshop), notice: "Invitations to #{audience} are being emailed out."
2✔
95
  end
96

97
  def destroy
6✔
98
    authorize(@workshop)
8✔
99

100
    if workshop_has_no_invitees? && workshop_created_within_specific_time_frame?
8✔
101
      @workshop.destroy
2✔
102

103
      redirect_to admin_root_path, notice: t('admin.workshop.destroy.success')
2✔
104
    else
105
      redirect_to admin_workshop_path(@workshop), notice: t('admin.workshop.destroy.failure')
6✔
106
    end
107
  end
108

109
  def changes
6✔
110
    invitations = @workshop.invitations
1✔
111
                           .where.not(attending: nil)
112
                           .includes(:member).order('members.name')
113

114
    @coach_invitations = invitations.to_coaches
1✔
115
    @student_invitations = invitations.to_students
1✔
116
  end
117

118
  def sponsor
6✔
NEW
119
    flash[:notice] = if workshop_sponsors.save
×
NEW
120
      'Sponsor added successfully'
×
121
    else
NEW
122
      workshop_sponsors.errors.full_messages.to_s
×
123
    end
NEW
124
    redirect_back fallback_location: root_path
×
125
  end
126

127
  def destroy_sponsor
6✔
NEW
128
    @sponsor = Sponsor.find(params[:sponsor_id])
×
NEW
129
    @workshop.workshop_sponsors.find_by(sponsor: @sponsor).destroy
×
NEW
130
    redirect_back fallback_location: root_path
×
131
  end
132

133
  def host
6✔
NEW
134
    set_sponsor
×
NEW
135
    @workshop_sponsor = WorkshopSponsor.find_or_create_by(workshop: @workshop, sponsor: @sponsor)
×
NEW
136
    @workshop_sponsor.update(host: true)
×
NEW
137
    flash[:notice] = 'Host set successfully'
×
138

NEW
139
    redirect_back fallback_location: root_path
×
140
  end
141

142
  def destroy_host
6✔
NEW
143
    @workshop.workshop_sponsors.find_by(host: true).update(host: false)
×
144

NEW
145
    redirect_back fallback_location: root_path
×
146
  end
147

148
  private
6✔
149

150
  def workshop_params
6✔
151
    params.expect(workshop: [
8✔
152
                    :local_date, :local_time, :local_end_time, :chapter_id,
153
                    :invitable, :seats, :virtual, :slack_channel, :slack_channel_link,
154
                    :rsvp_open_local_date, :rsvp_open_local_time, :description,
155
                    :rsvp_close_local_date, :rsvp_close_local_time,
156
                    :coach_spaces, :student_spaces,
157
                    { sponsor_ids: [] }
158
                  ])
159
  end
160

161
  def chapter_id
6✔
162
    params.permit(:chapter_id)[:chapter_id]
1✔
163
  end
164

165
  def set_workshop_by_id
6✔
166
    @workshop = Workshop.find(params[:id])
40✔
167
  end
168

169
  def set_and_decorate_workshop
6✔
170
    workshop = Workshop.find(params[:workshop_id])
6✔
171
    @workshop = WorkshopPresenter.decorate(workshop)
6✔
172
  end
173

174
  def workshop_id
6✔
175
    params.permit(:workshop_id)[:workshop_id]
×
176
  end
177

178
  def assign_host(host_id)
6✔
179
    return unless host_id
4✔
180

181
    host = @workshop.workshop_sponsors.find_or_initialize_by(sponsor_id: host_id)
4✔
182
    return if @workshop.host.eql?(host.sponsor)
4✔
183

184
    @workshop.workshop_sponsors.where(sponsor: @workshop.host).destroy_all
2✔
185
    host.update(host: true)
2✔
186
  end
187

188
  def assign_organisers(organiser_ids)
6✔
189
    organiser_ids.reject!(&:empty?)
1✔
190
    grant_organiser_access(organiser_ids)
1✔
191
    revoke_organiser_access(organiser_ids)
1✔
192
  end
193

194
  def host_id
6✔
195
    params.expect(workshop: [:host])[:host]
10✔
196
  end
197

198
  def organiser_ids
6✔
199
    params[:workshop][:organisers]
1✔
200
  end
201

202
  def grant_organiser_access(organiser_ids = [])
6✔
203
    organiser_ids.each { |id| Member.find(id).add_role(:organiser, @workshop) }
7✔
204
  end
205

206
  def revoke_organiser_access(organiser_ids)
6✔
207
    (@workshop.organisers.pluck(:id).map(&:to_s) - organiser_ids).each do |id|
1✔
208
      Member.find(id).revoke(:organiser, @workshop)
×
209
    end
210
  end
211

212
  def workshop_has_no_invitees?
6✔
213
    @workshop.invitations.blank?
8✔
214
  end
215

216
  def workshop_created_within_specific_time_frame?
6✔
217
    Time.zone.now.between?(@workshop.created_at,
4✔
218
                           @workshop.created_at + WORKSHOP_DELETION_TIME_FRAME_SINCE_CREATION)
219
  end
220

221
  def physical_workshop_and_no_host?(workshop)
6✔
222
    !workshop.virtual && host_id.empty?
8✔
223
  end
224

225
  def workshop_type_valid?
6✔
226
    return true unless physical_workshop_and_no_host?(@workshop)
8✔
227

228
    @workshop.errors.add(:host, "can't be blank")
2✔
229
    false
2✔
230
  end
231

232
  def update_workshop_details
6✔
233
    assign_organisers(organiser_ids)
1✔
234
    assign_host(host_id)
1✔
235
  end
236

237
  def set_sponsor
6✔
NEW
238
    @sponsor = Sponsor.find(params[:workshop][:sponsor_ids])
×
239
  end
240

241
  def workshop_sponsor(host = false)
6✔
NEW
242
    @workshop_sponsor ||= WorkshopSponsor.new(workshop: @workshop, sponsor: @sponsor, host: host)
×
243
  end
244
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc