Class: Event

Inherits:
ApplicationRecord show all
Includes:
CreatedAtFilterable, DeleteWithLimit, EachBatch, FromUnion, Gitlab::Utils::StrongMemoize, Import::HasImportSource, Presentable, ShaAttribute, Sortable, UsageStatistics
Defined in:
app/models/event.rb

Direct Known Subclasses

PushEvent

Constant Summary collapse

PROJECT_ACTIONS =
[:created, :pushed, :joined, :left, :expired].freeze
WIKI_ACTIONS =
[:created, :updated, :destroyed].freeze
DESIGN_ACTIONS =
[:created, :updated, :destroyed].freeze
TEAM_ACTIONS =
[:joined, :left, :expired].freeze
ISSUE_ACTIONS =
[:created, :updated, :closed, :reopened].freeze
ISSUE_TYPES =
[Issue.name, WorkItem.name].freeze
TARGET_TYPES =
HashWithIndifferentAccess.new(
  issue: Issue,
  milestone: Milestone,
  merge_request: MergeRequest,
  note: Note,
  project: Project,
  snippet: Snippet,
  user: User,
  wiki: WikiPage::Meta,
  design: DesignManagement::Design
).freeze
RESET_PROJECT_ACTIVITY_INTERVAL =
1.hour
REPOSITORY_UPDATED_AT_INTERVAL =
5.minutes
CONTRIBUTABLE_TARGET_TYPES =
%w[MergeRequest Issue WorkItem DesignManagement::Design].freeze

Constants included from Import::HasImportSource

Import::HasImportSource::IMPORT_SOURCES

Constants inherited from ApplicationRecord

ApplicationRecord::MAX_PLUCK

Constants included from HasCheckConstraints

HasCheckConstraints::NOT_NULL_CHECK_PATTERN

Constants included from ResetOnColumnErrors

ResetOnColumnErrors::MAX_RESET_PERIOD

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Import::HasImportSource

#imported?

Methods inherited from ApplicationRecord

===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order

Methods included from Organizations::Sharding

#sharding_organization

Methods included from ResetOnColumnErrors

#reset_on_union_error, #reset_on_unknown_attribute_error

Methods included from Gitlab::SensitiveSerializableHash

#serializable_hash

Class Method Details

.find_sti_class(action) ⇒ Object



158
159
160
161
162
163
164
# File 'app/models/event.rb', line 158

def find_sti_class(action)
  if actions.fetch(action, action) == actions[:pushed] # action can be integer or symbol
    PushEvent
  else
    Event
  end
end

.limit_recent(limit = 20, offset = nil) ⇒ Object



166
167
168
# File 'app/models/event.rb', line 166

def limit_recent(limit = 20, offset = nil)
  recent.limit(limit).offset(offset)
end

.model_nameObject



154
155
156
# File 'app/models/event.rb', line 154

def model_name
  ActiveModel::Name.new(self, nil, 'event')
end

.target_typesObject



170
171
172
# File 'app/models/event.rb', line 170

def target_types
  TARGET_TYPES.keys
end

Instance Method Details

#action_nameObject

rubocop: disable Metrics/CyclomaticComplexity rubocop: disable Metrics/PerceivedComplexity



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'app/models/event.rb', line 299

def action_name
  if push_action?
    push_action_name
  elsif design?
    design_action_names[action.to_sym]
  elsif closed_action?
    "closed"
  elsif merged_action?
    "accepted"
  elsif joined_action?
    'joined'
  elsif left_action?
    'left'
  elsif expired_action?
    'removed due to membership expiration from'
  elsif destroyed_action?
    'destroyed'
  elsif commented_action?
    "commented on"
  elsif created_wiki_page?
    'created'
  elsif updated_wiki_page?
    'updated'
  elsif created_project_action?
    created_project_action_name
  elsif approved_action?
    'approved'
  else
    "opened"
  end
end

#authored_by?(user) ⇒ Boolean

Returns:

  • (Boolean)


434
435
436
# File 'app/models/event.rb', line 434

def authored_by?(user)
  user ? author_id == user.id : false
end

#body?Boolean

Returns:

  • (Boolean)


395
396
397
398
399
400
401
402
403
# File 'app/models/event.rb', line 395

def body?
  if push_action?
    push_with_commits?
  elsif note?
    true
  else
    target.respond_to? :title
  end
end

#commit_note?Boolean

Returns:

  • (Boolean)


338
339
340
# File 'app/models/event.rb', line 338

def commit_note?
  note? && target && target.for_commit?
end

#created_project_action?Boolean

Returns:

  • (Boolean)


203
204
205
# File 'app/models/event.rb', line 203

def created_project_action?
  project? && created_action?
end

#created_target?Boolean

Returns:

  • (Boolean)


215
216
217
# File 'app/models/event.rb', line 215

def created_target?
  created_action? && target
end

#created_wiki_page?Boolean

Returns:

  • (Boolean)


207
208
209
# File 'app/models/event.rb', line 207

def created_wiki_page?
  wiki_page? && created_action?
end

#designObject



277
278
279
# File 'app/models/event.rb', line 277

def design
  target if design?
end

#design?Boolean

Returns:

  • (Boolean)


239
240
241
# File 'app/models/event.rb', line 239

def design?
  target_type == 'DesignManagement::Design'
end

#design_note?Boolean

Returns:

  • (Boolean)


362
363
364
# File 'app/models/event.rb', line 362

def design_note?
  note? && note.for_design?
end

#ensure_sharding_keyObject



405
406
407
408
409
# File 'app/models/event.rb', line 405

def ensure_sharding_key
  return unless group_id.nil? && project_id.nil? && personal_namespace_id.nil?

  self.personal_namespace_id = author.namespace_id
end

#has_no_project_and_group?Boolean

Returns:

  • (Boolean)


444
445
446
# File 'app/models/event.rb', line 444

def has_no_project_and_group?
  project_id.nil? && group_id.nil?
end

#issueObject



273
274
275
# File 'app/models/event.rb', line 273

def issue
  target if issue?
end

#issue?Boolean

Returns:

  • (Boolean)


227
228
229
# File 'app/models/event.rb', line 227

def issue?
  target_type == "Issue"
end

#issue_note?Boolean

Returns:

  • (Boolean)


342
343
344
# File 'app/models/event.rb', line 342

def issue_note?
  note? && target && target.for_issue?
end

#membership_changed?Boolean

Returns:

  • (Boolean)


199
200
201
# File 'app/models/event.rb', line 199

def membership_changed?
  joined_action? || left_action? || expired_action?
end

#merge_requestObject



281
282
283
# File 'app/models/event.rb', line 281

def merge_request
  target if merge_request?
end

#merge_request?Boolean

Returns:

  • (Boolean)


231
232
233
# File 'app/models/event.rb', line 231

def merge_request?
  target_type == "MergeRequest"
end

#merge_request_note?Boolean

Returns:

  • (Boolean)


346
347
348
# File 'app/models/event.rb', line 346

def merge_request_note?
  note? && target && target.for_merge_request?
end

#milestoneObject



269
270
271
# File 'app/models/event.rb', line 269

def milestone
  target if milestone?
end

#milestone?Boolean

Returns:

  • (Boolean)


219
220
221
# File 'app/models/event.rb', line 219

def milestone?
  target_type == "Milestone"
end

#noteObject



293
294
295
# File 'app/models/event.rb', line 293

def note
  target if note?
end

#note?Boolean

Returns:

  • (Boolean)


223
224
225
# File 'app/models/event.rb', line 223

def note?
  target.is_a?(Note)
end

#note_targetObject



370
371
372
# File 'app/models/event.rb', line 370

def note_target
  target.noteable
end

#note_target_idObject



374
375
376
377
378
379
380
# File 'app/models/event.rb', line 374

def note_target_id
  if commit_note?
    target.commit_id
  else
    target.noteable_id.to_s
  end
end

#note_target_referenceObject



382
383
384
385
386
387
388
389
390
391
392
393
# File 'app/models/event.rb', line 382

def note_target_reference
  return unless note_target

  # Commit#to_reference returns the full SHA, but we want the short one here
  if commit_note?
    note_target.short_id
  elsif wiki_page_note?
    note_target.reference_link_text
  else
    note_target.to_reference
  end
end

#personal_snippet_note?Boolean

Returns:

  • (Boolean)


358
359
360
# File 'app/models/event.rb', line 358

def personal_snippet_note?
  note? && target && target.for_personal_snippet?
end

#presentObject



175
176
177
# File 'app/models/event.rb', line 175

def present
  super(presenter_class: ::EventPresenter)
end

#project?Boolean

Returns:

  • (Boolean)


247
248
249
# File 'app/models/event.rb', line 247

def project?
  target_type == 'Project'
end

#project_snippet_note?Boolean

Returns:

  • (Boolean)


354
355
356
# File 'app/models/event.rb', line 354

def project_snippet_note?
  note? && target && target.for_project_snippet?
end

#push_action?Boolean

Returns:

  • (Boolean)


195
196
197
# File 'app/models/event.rb', line 195

def push_action?
  false
end

#reset_project_activityObject



418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# File 'app/models/event.rb', line 418

def reset_project_activity
  return unless project_id.present?

  # Don't bother updating if we know the project was updated recently.
  return if recent_update?

  # At this point it's possible for multiple threads/processes to try to
  # update the project. Only one query should actually perform the update,
  # hence we add the extra WHERE clause for last_activity_at.
  Project.unscoped.where(id: project_id)
    .where('last_activity_at <= ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago)
    .touch_all(:last_activity_at, time: created_at)

  Gitlab::DormantProjectsDeletionWarningTracker.new(project_id).reset
end

#resource_parentObject



187
188
189
# File 'app/models/event.rb', line 187

def resource_parent
  project || group
end

#snippet_note?Boolean

Returns:

  • (Boolean)


350
351
352
# File 'app/models/event.rb', line 350

def snippet_note?
  note? && target && target.for_snippet?
end

#targetObject



263
264
265
266
267
# File 'app/models/event.rb', line 263

def target
  return project if super.nil? && project?

  super
end

#target_idObject



257
258
259
260
261
# File 'app/models/event.rb', line 257

def target_id
  return project_id if super.nil? && project?

  super
end

#target_iidObject

rubocop: enable Metrics/CyclomaticComplexity rubocop: enable Metrics/PerceivedComplexity



334
335
336
# File 'app/models/event.rb', line 334

def target_iid
  target.respond_to?(:iid) ? target.iid : target_id
end

#target_titleObject



191
192
193
# File 'app/models/event.rb', line 191

def target_title
  target.try(:title)
end

#target_typeObject



251
252
253
254
255
# File 'app/models/event.rb', line 251

def target_type
  return 'Project' if project_as_target?(super)

  super
end

#to_partial_pathObject



438
439
440
441
442
# File 'app/models/event.rb', line 438

def to_partial_path
  # We are intentionally using `Event` rather than `self.class` so that
  # subclasses also use the `Event` implementation.
  Event._to_partial_path
end

#update_projectObject



411
412
413
414
415
416
# File 'app/models/event.rb', line 411

def update_project
  return unless project_id.present?

  reset_project_activity
  set_last_repository_updated_at if push_action?
end

#updated_wiki_page?Boolean

Returns:

  • (Boolean)


211
212
213
# File 'app/models/event.rb', line 211

def updated_wiki_page?
  wiki_page? && updated_action?
end

#visible_to_user?(user = nil) ⇒ Boolean

Returns:

  • (Boolean)


179
180
181
182
183
184
185
# File 'app/models/event.rb', line 179

def visible_to_user?(user = nil)
  return false unless capability.present?

  capability.all? do |rule|
    Ability.allowed?(user, rule, permission_object)
  end
end

#wiki_pageObject



285
286
287
288
289
290
291
# File 'app/models/event.rb', line 285

def wiki_page
  strong_memoize(:wiki_page) do
    next unless wiki_page?

    Wiki.for_container(project || group, author).find_page(target.canonical_slug)
  end
end

#wiki_page?Boolean

Returns:

  • (Boolean)


235
236
237
# File 'app/models/event.rb', line 235

def wiki_page?
  target_type == 'WikiPage::Meta'
end

#wiki_page_note?Boolean

Returns:

  • (Boolean)


366
367
368
# File 'app/models/event.rb', line 366

def wiki_page_note?
  note? && note.for_wiki_page?
end

#work_item?Boolean

Returns:

  • (Boolean)


243
244
245
# File 'app/models/event.rb', line 243

def work_item?
  target_type == 'WorkItem'
end