Class: User

Constant Summary collapse

VALID_COUNTRY_NAMES =
['Afghanistan', 'Åland', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bonaire', 'Bosnia and Herzegovina', 'Botswana', 'Brazil', 'British Indian Ocean Territory', 'British Virgin Islands', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burundi', 'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Cayman Islands', 'Central African Republic', 'Chad', 'Chile', 'China', 'Christmas Island', 'Cocos [Keeling], Islands', 'Colombia', 'Comoros', 'Congo', 'Cook Islands', 'Costa Rica', 'Croatia', 'Cuba', 'Curaçao', 'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Falkland Islands', 'Faroe Islands', 'Federated States of Micronesia', 'Fiji', 'Finland', 'France', 'French Guiana', 'French Polynesia', 'French Southern Territories', 'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar', 'Greece', 'Greenland', 'Grenada', 'Guadeloupe', 'Guam', 'Guatemala', 'Guernsey', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Hashemite Kingdom of Jordan', 'Honduras', 'Hong Kong', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Isle of Man', 'Israel', 'Italy', 'Ivory Coast', 'Jamaica', 'Japan', 'Jersey', 'Kazakhstan', 'Kenya', 'Kiribati', 'Kosovo', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein', 'Luxembourg', 'Macao', 'Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Marshall Islands', 'Martinique', 'Mauritania', 'Mauritius', 'Mayotte', 'Mexico', 'Monaco', 'Mongolia', 'Montenegro', 'Montserrat', 'Morocco', 'Mozambique', 'Myanmar [Burma],', 'Namibia', 'Nauru', 'Nepal', 'Netherlands', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', 'North Korea', 'Northern Mariana Islands', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Palestine', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Pitcairn Islands', 'Poland', 'Portugal', 'Puerto Rico', 'Qatar', 'Republic of Korea', 'Republic of Lithuania', 'Republic of Moldova', 'Republic of the Congo', 'Réunion', 'Romania', 'Russia', 'Rwanda', 'Saint Helena', 'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Martin', 'Saint Pierre and Miquelon', 'Saint Vincent and the Grenadines', 'Saint-Barthélemy', 'Samoa', 'San Marino', 'São Tomé and Príncipe', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Sint Maarten', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Georgia and the South Sandwich Islands', 'South Sudan', 'Spain', 'Sri Lanka', 'Sudan', 'Suriname', 'Svalbard and Jan Mayen', 'Swaziland', 'Sweden', 'Switzerland', 'Syria', 'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', 'Togo', 'Tokelau', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks and Caicos Islands', 'Tuvalu', 'U.S. Minor Outlying Islands', 'U.S. Virgin Islands', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan', 'Vanuatu', 'Vatican City', 'Venezuela', 'Vietnam', 'Wallis and Futuna', 'Yemen', 'Zambia', 'Zimbabwe'].freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

#obj_type, #reindex, #sanitize, #sanitize_content, #sanitize_description

Methods included from Skillable

#update_skills

Methods included from Ressourceable

#update_ressources

Methods included from RelationHelpers

#clappers, #followers, #followers_count

Methods included from RecsysHelpers

#add_edge, #remove_edge

Methods included from NotificationsHelpers

#notif_new_member, #notif_pending_member

Methods included from Interestable

#update_interests

Methods included from Feedable

#posts_count

Methods included from Coordinates

#create_coordinates

Methods included from Avatarable

#logo_url, #logo_url_sm

Methods included from AffiliatableChild

#add_affiliation_to, #remove_affiliation_to

Class Method Details

.to_csv(users) ⇒ Object



329
330
331
332
333
334
335
336
337
# File 'app/models/user.rb', line 329

def self.to_csv(users)
  attributes = %w[id first_name last_name email] #customize columns here
  CSV.generate(headers: true) do |csv|
    csv << attributes
    users.each do |user|
      csv << attributes.map{ |attr| user.send(attr) }
    end
  end
end

Instance Method Details

#active_at!Object



89
90
91
# File 'app/models/user.rb', line 89

def active_at!
  update(last_active_at: DateTime.now)
end

#add_role(*args) ⇒ Object



281
282
283
284
285
286
# File 'app/models/user.rb', line 281

def add_role(*args)
  super(*args)
  # args[1] will be some resource that had a user role added to it, so let's reindex it
  # so it's user counts are accurate
  args[1]&.index!
end

#ageObject



269
270
271
272
273
# File 'app/models/user.rb', line 269

def age
  return calculate_age if birth_date.present?

  self[:age]
end

#booleanify(value) ⇒ Object



303
304
305
# File 'app/models/user.rb', line 303

def booleanify(value)
  ActiveModel::Type::Boolean.new.cast(value)
end

#challengesObject



97
98
99
# File 'app/models/user.rb', line 97

def challenges
  Challenge.where(id: roles.where(resource_type: 'Challenge').pluck(:resource_id))
end

#challenges_countObject



130
131
132
# File 'app/models/user.rb', line 130

def challenges_count
  challenges.count
end

#clapped?(object) ⇒ Boolean

Returns:

  • (Boolean)


182
183
184
# File 'app/models/user.rb', line 182

def clapped?(object)
  owned_relations.where(resource: object).clapped.any?
end

#claps_countObject

override RelationHelpers for user (because it's owned_relations and not relations)



157
158
159
# File 'app/models/user.rb', line 157

def claps_count
  owned_relations.saved.size
end

#direct_message_limit_reached?Boolean

a worker resets this limit on the first day of each month

Returns:

  • (Boolean)


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

def direct_message_limit_reached?
  message_limit = ENV['DIRECT_MESSAGE_LIMIT'] || 20
  direct_message_count >= message_limit
end

#follow_mutual(user) ⇒ Object

Returns the users that self and user are following together (Or the interesection of their follow).



166
167
168
169
170
171
# File 'app/models/user.rb', line 166

def follow_mutual(user)
  mine = Set.new(owned_relations.follows.of_type('User').pluck(:resource_id))
  other = Set.new(user.owned_relations.follows.of_type('User').pluck(:resource_id))
  mutual = mine.intersection(other)
  User.where(id: mutual)
end

#follow_mutual_count(user) ⇒ Object



173
174
175
# File 'app/models/user.rb', line 173

def follow_mutual_count(user)
  follow_mutual(user).count
end

#followingObject



222
223
224
# File 'app/models/user.rb', line 222

def following
  owned_relations.follows
end

#following_countObject



218
219
220
# File 'app/models/user.rb', line 218

def following_count
  following.size
end

#follows?(object) ⇒ Boolean

helpers for relation state.

Returns:

  • (Boolean)


178
179
180
# File 'app/models/user.rb', line 178

def follows?(object)
  owned_relations.where(resource: object).follows.any?
end


214
215
216
# File 'app/models/user.rb', line 214

def frontend_link
  "/user/#{id}"
end

#full_nameObject Also known as: title



208
209
210
# File 'app/models/user.rb', line 208

def full_name
  "#{first_name} #{last_name}"
end

#has_badge?(badge_name) ⇒ Boolean

Returns:

  • (Boolean)


204
205
206
# File 'app/models/user.rb', line 204

def has_badge?(badge_name)
  badges.any? { |badge| badge_name == badge.name }
end

#mailchimpObject



194
195
196
# File 'app/models/user.rb', line 194

def mailchimp
  MailchimpSubscriber.perform_async(id, mail_newsletter)
end

#make_addressObject



198
199
200
201
202
# File 'app/models/user.rb', line 198

def make_address
  return ip unless city.present?

  super
end

#needsObject



113
114
115
# File 'app/models/user.rb', line 113

def needs
  Need.where(id: roles.where(resource_type: 'Need').pluck(:resource_id))
end

#needs_countObject



122
123
124
# File 'app/models/user.rb', line 122

def needs_count
  Need.with_role(:member, self).size
end

#notif_new_clap(clapper) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
# File 'app/models/user.rb', line 245

def notif_new_clap(clapper)
  Notification.create(
    target: self,
    category: :clap,
    type: 'new_clap',
    object: self,
    metadata: {
      clapper: clapper
    }
  )
end

#notif_new_follower(follower) ⇒ Object



236
237
238
239
240
241
242
243
# File 'app/models/user.rb', line 236

def notif_new_follower(follower)
  Notification.create(
    target: self,
    category: :follow,
    type: 'new_user_follower',
    object: follower
  )
end

#notif_new_post_on_profile_feedObject



257
258
259
260
261
262
263
264
265
266
267
# File 'app/models/user.rb', line 257

def notif_new_post_on_profile_feed
  Notification.for_group(
    :user_followers,
    args: [self],
    attrs: {
      category: :feed,
      type: 'new_post_on_profile_feed',
      object: self
    }
  )
end

#owned_posts_countObject



142
143
144
# File 'app/models/user.rb', line 142

def owned_posts_count
  posts.size
end

#programsObject



105
106
107
# File 'app/models/user.rb', line 105

def programs
  Program.where(id: roles.where(resource_type: 'Program').pluck(:resource_id))
end

#programs_countObject



134
135
136
# File 'app/models/user.rb', line 134

def programs_count
  programs.count
end

#projectsObject



93
94
95
# File 'app/models/user.rb', line 93

def projects
  Project.where(id: roles.where(resource_type: 'Project').pluck(:resource_id))
end

#projects_countObject



117
118
119
120
# File 'app/models/user.rb', line 117

def projects_count
  # Use the roles relation to filter projects where the user is a member
  roles.where(name: 'member', resource_type: 'Project').size
end

#reviewed?(object) ⇒ Boolean

Returns:

  • (Boolean)


190
191
192
# File 'app/models/user.rb', line 190

def reviewed?(object)
  owned_relations.where(resource: object).reviewed.any?
end

#reviews_countObject

override RelationHelpers for user (because it's owned_relations and not relations)



152
153
154
# File 'app/models/user.rb', line 152

def reviews_count
  owned_relations.saved.size
end

#saved?(object) ⇒ Boolean

Returns:

  • (Boolean)


186
187
188
# File 'app/models/user.rb', line 186

def saved?(object)
  owned_relations.where(resource: object).saved.any?
end

#saves_countObject

override RelationHelpers for user (because it's owned_relations and not relations)



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

def saves_count
  owned_relations.saved.size
end

#set_defaultsObject



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'app/models/user.rb', line 307

def set_defaults
  # Hashie::Mash is expected by the notifications gem
  settings = Hashie::Mash.new(
    enabled: true,
    categories: {},
    delivery_methods: {}
  )

  NotificationSettings.configuration.categories.each do |category|
    settings[:categories][category] = { enabled: true, delivery_methods: {} }
    NotificationPusher.configuration.delivery_methods.each do |delivery_method, _|
      settings[:categories][category][:delivery_methods][delivery_method] = { enabled: true }
    end
  end

  NotificationPusher.configuration.delivery_methods.each do |delivery_method, _|
    settings[:delivery_methods][delivery_method] = { enabled: true }
  end

  self.settings = settings
end

#set_settings(new_settings) ⇒ Object



288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'app/models/user.rb', line 288

def set_settings(new_settings)
  # Hashie::Mash syntax is
  settings.enabled = booleanify(new_settings[:enabled])
  new_settings[:categories]&.each do |category, _value|
    settings.categories!.send("#{category}!").enabled = booleanify(new_settings[:categories][category][:enabled])
    new_settings[:categories][category][:delivery_methods].each do |delivery_method, _value|
      settings.categories!.send("#{category}!").delivery_methods!.send("#{delivery_method}!").enabled = booleanify(new_settings[:categories][category][:delivery_methods][delivery_method][:enabled])
    end
  end
  new_settings[:delivery_methods]&.each do |delivery_method, _value|
    settings.delivery_methods!.send("#{delivery_method}!").enabled = booleanify(new_settings[:delivery_methods][delivery_method][:enabled])
  end
  save
end

#skip_duplicate_devise_confirmation_emailObject

Fixes problem with duplicate account confirmation emails



83
84
85
# File 'app/models/user.rb', line 83

def skip_duplicate_devise_confirmation_email
  skip_confirmation_notification!
end

#spacesObject



109
110
111
# File 'app/models/user.rb', line 109

def spaces
  Space.where(id: roles.where(resource_type: 'Space').pluck(:resource_id))
end

#spaces_countObject



138
139
140
# File 'app/models/user.rb', line 138

def spaces_count
  spaces.count
end

#timeline_postsObject



226
227
228
229
230
231
232
233
234
# File 'app/models/user.rb', line 226

def timeline_posts
  # using IDs because concating onto feed.posts actually creates a feeds_posts record
  # and adds the post to the user's feeds permanently
  posts_ids = feed.post_ids
  following.map do |object|
    posts_ids.concat(object.resource.feed.post_ids) if object && object.resource && object.resource.feed && object.resource.feed.post_ids && object.resource.present?
  end
  Post.where(id: posts_ids).distinct(:id).order(created_at: :desc)
end

#token_validation_responseObject



161
162
163
# File 'app/models/user.rb', line 161

def token_validation_response
  Api::UserSigninSerializer.new(self, root: false).as_json
end

#workgroupsObject



101
102
103
# File 'app/models/user.rb', line 101

def workgroups
  Workgroup.where(id: roles.where(resource_type: 'Workgroup').pluck(:resource_id))
end

#workgroups_countObject



126
127
128
# File 'app/models/user.rb', line 126

def workgroups_count
  Workgroup.with_role(:member, self).size
end