Class: Badge

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
GlobalPath, HasSanitizableFields
Defined in:
app/models/badge.rb

Defined Under Namespace

Modules: Trigger

Constant Summary collapse

BasicUser =

NOTE: These badge ids are not in order! They are grouped logically.

When picking an id, *search* for it.
1
Member =
2
Regular =
3
Leader =
4
Welcome =
5
NicePost =
6
GoodPost =
7
GreatPost =
8
Autobiographer =
9
Editor =
10
WikiEditor =
48
FirstLike =
11
FirstShare =
12
FirstFlag =
13
14
FirstQuote =
15
FirstMention =
40
FirstEmoji =
41
FirstOnebox =
42
FirstReplyByEmail =
43
ReadGuidelines =
16
Reader =
17
NiceTopic =
18
GoodTopic =
19
GreatTopic =
20
NiceShare =
21
GoodShare =
22
GreatShare =
23
Anniversary =
24
Promoter =
25
Campaigner =
26
Champion =
27
28
29
30
Appreciated =
36
Respected =
37
Admired =
31
OutOfLove =
33
HigherLove =
34
CrazyInLove =
35
ThankYou =
38
GivesBack =
32
Empathetic =
39
Enthusiast =
45
Aficionado =
46
Devotee =
47
NewUserOfTheMonth =
44
AutobiographerMinBioLength =

other consts

10

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasSanitizableFields

#sanitize_field

Methods included from GlobalPath

#cdn_path, #cdn_relative_path, #full_cdn_url, #path, #upload_cdn_path

Instance Attribute Details

#has_badgeObject

used by serializer



76
77
78
# File 'app/models/badge.rb', line 76

def has_badge
  @has_badge
end

Class Method Details

.display_name(name) ⇒ Object



228
229
230
# File 'app/models/badge.rb', line 228

def self.display_name(name)
  I18n.t(i18n_key(name), default: name)
end

.ensure_consistency!Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/models/badge.rb', line 162

def self.ensure_consistency!
  DB.exec <<~SQL
    DELETE FROM user_badges
          USING user_badges ub
      LEFT JOIN users u ON u.id = ub.user_id
          WHERE u.id IS NULL
            AND user_badges.id = ub.id
  SQL

  DB.exec <<~SQL
    WITH X AS (
        SELECT badge_id
             , COUNT(user_id) users
          FROM user_badges
      GROUP BY badge_id
    )
    UPDATE badges
       SET grant_count = X.users
      FROM X
     WHERE id = X.badge_id
       AND grant_count <> X.users
  SQL
end

.find_system_badge_id_from_translation_key(translation_key) ⇒ Object



236
237
238
239
240
# File 'app/models/badge.rb', line 236

def self.find_system_badge_id_from_translation_key(translation_key)
  return unless translation_key.starts_with?("badges.")
  badge_name_klass = translation_key.split(".").second.camelize
  Badge.const_defined?(badge_name_klass) ? "Badge::#{badge_name_klass}".constantize : nil
end

.i18n_key(name) ⇒ Object



232
233
234
# File 'app/models/badge.rb', line 232

def self.i18n_key(name)
  "badges.#{i18n_name(name)}.name"
end

.i18n_name(name) ⇒ Object



224
225
226
# File 'app/models/badge.rb', line 224

def self.i18n_name(name)
  name.to_s.downcase.tr(" ", "_")
end

.like_badge_countsObject



151
152
153
154
155
156
157
158
159
160
# File 'app/models/badge.rb', line 151

def self.like_badge_counts
  @like_badge_counts ||= {
    NicePost => 10,
    GoodPost => 25,
    GreatPost => 50,
    NiceTopic => 10,
    GoodTopic => 25,
    GreatTopic => 50,
  }
end

.protected_system_fieldsObject

fields that can not be edited on system badges



143
144
145
# File 'app/models/badge.rb', line 143

def self.protected_system_fields
  %i[name badge_type_id multiple_grant target_posts show_posts query trigger auto_revoke listable]
end

.trigger_hashObject



78
79
80
81
82
83
84
85
86
87
88
# File 'app/models/badge.rb', line 78

def self.trigger_hash
  @trigger_hash ||=
    Badge::Trigger
      .constants
      .map do |k|
        name = k.to_s.underscore
        [name, Badge::Trigger.const_get(k)] unless name =~ /deprecated/
      end
      .compact
      .to_h
end

.trust_level_badge_idsObject



147
148
149
# File 'app/models/badge.rb', line 147

def self.trust_level_badge_ids
  (1..4).to_a
end

Instance Method Details

#awarded_for_trust_level?Boolean

Returns:

  • (Boolean)


242
243
244
# File 'app/models/badge.rb', line 242

def awarded_for_trust_level?
  id <= 4
end

#clear_user_titles!Object



186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'app/models/badge.rb', line 186

def clear_user_titles!
  DB.exec(<<~SQL, badge_id: self.id, updated_at: Time.zone.now)
    UPDATE users AS u
    SET title = '', updated_at = :updated_at
    FROM user_profiles AS up
    WHERE up.user_id = u.id AND up.granted_title_badge_id = :badge_id
  SQL
  DB.exec(<<~SQL, badge_id: self.id)
    UPDATE user_profiles AS up
    SET granted_title_badge_id = NULL
    WHERE up.granted_title_badge_id = :badge_id
  SQL
end

#default_allow_title=(val) ⇒ Object



262
263
264
265
# File 'app/models/badge.rb', line 262

def default_allow_title=(val)
  return if !self.new_record?
  self.allow_title = val
end

#default_badge_grouping_id=(val) ⇒ Object



272
273
274
275
276
277
# File 'app/models/badge.rb', line 272

def default_badge_grouping_id=(val)
  # allow to correct orphans
  if !self.badge_grouping_id || self.badge_grouping_id <= BadgeGrouping::Other
    self.badge_grouping_id = val
  end
end

#default_enabled=(val) ⇒ Object



267
268
269
270
# File 'app/models/badge.rb', line 267

def default_enabled=(val)
  return if !self.new_record?
  self.enabled = val
end

#default_icon=(val) ⇒ Object



255
256
257
258
259
260
# File 'app/models/badge.rb', line 255

def default_icon=(val)
  if self.image_upload_id.blank?
    self.icon ||= val
    self.icon = val if self.icon == "fa-certificate"
  end
end

#descriptionObject



302
303
304
305
306
307
308
309
310
# File 'app/models/badge.rb', line 302

def description
  key = "badges.#{i18n_name}.description"
  I18n.t(
    key,
    default: self[:description] || "",
    base_uri: Discourse.base_path,
    max_likes_per_day: SiteSetting.max_likes_per_day,
  )
end

#description=(val) ⇒ Object



312
313
314
315
# File 'app/models/badge.rb', line 312

def description=(val)
  self[:description] = val if val != description
  val
end

#display_nameObject



279
280
281
# File 'app/models/badge.rb', line 279

def display_name
  self.class.display_name(name)
end

#for_beginners?Boolean

Returns:

  • (Boolean)


333
334
335
# File 'app/models/badge.rb', line 333

def for_beginners?
  id == Welcome || (badge_grouping_id == BadgeGrouping::GettingStarted && id != NewUserOfTheMonth)
end

#i18n_nameObject



325
326
327
# File 'app/models/badge.rb', line 325

def i18n_name
  @i18n_name ||= self.class.i18n_name(name)
end

#image_urlObject



329
330
331
# File 'app/models/badge.rb', line 329

def image_url
  upload_cdn_path(image_upload.url) if image_upload_id.present?
end

#long_descriptionObject



287
288
289
290
291
292
293
294
295
# File 'app/models/badge.rb', line 287

def long_description
  key = "badges.#{i18n_name}.long_description"
  I18n.t(
    key,
    default: self[:long_description] || "",
    base_uri: Discourse.base_path,
    max_likes_per_day: SiteSetting.max_likes_per_day,
  )
end

#long_description=(val) ⇒ Object



297
298
299
300
# File 'app/models/badge.rb', line 297

def long_description=(val)
  self[:long_description] = val if val != long_description
  val
end

#manually_grantable?Boolean

Returns:

  • (Boolean)


321
322
323
# File 'app/models/badge.rb', line 321

def manually_grantable?
  query.blank? && !system?
end

#reset_grant_count!Object



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

def reset_grant_count!
  self.grant_count = UserBadge.where(badge_id: id).count
  save!
end

#reset_user_titles!Object

When a badge has its TranslationOverride cleared, reset all user titles granted to the standard name.



214
215
216
217
218
219
220
221
222
# File 'app/models/badge.rb', line 214

def reset_user_titles!
  DB.exec(<<~SQL, granted_title_badge_id: self.id, updated_at: Time.zone.now)
    UPDATE users AS u
    SET title = badges.name, updated_at = :updated_at
    FROM user_profiles AS up
    INNER JOIN badges ON badges.id = up.granted_title_badge_id
    WHERE up.user_id = u.id AND up.granted_title_badge_id = :granted_title_badge_id
  SQL
end

#single_grant?Boolean

Returns:

  • (Boolean)


251
252
253
# File 'app/models/badge.rb', line 251

def single_grant?
  !self.multiple_grant?
end

#slugObject



317
318
319
# File 'app/models/badge.rb', line 317

def slug
  Slug.for(self.display_name, "-")
end

#translation_keyObject



283
284
285
# File 'app/models/badge.rb', line 283

def translation_key
  self.class.i18n_key(name)
end

#update_user_titles!(new_title) ⇒ Object

Update all user titles based on a badge to the new name



202
203
204
205
206
207
208
209
# File 'app/models/badge.rb', line 202

def update_user_titles!(new_title)
  DB.exec(<<~SQL, granted_title_badge_id: self.id, title: new_title, updated_at: Time.zone.now)
    UPDATE users AS u
    SET title = :title, updated_at = :updated_at
    FROM user_profiles AS up
    WHERE up.user_id = u.id AND up.granted_title_badge_id = :granted_title_badge_id
  SQL
end