3
3
# Table name: social_profiles
4
4
#
5
5
# id :integer not null, primary key
6
- # provider :integer
7
- # sociable_type :string indexed => [sociable_id]
8
- # value :string
6
+ # provider :string not null
7
+ # sociable_type :string not null, indexed => [sociable_id]
8
+ # value :string not null
9
9
# created_at :datetime not null
10
10
# updated_at :datetime not null
11
- # sociable_id :integer indexed => [sociable_type]
11
+ # sociable_id :integer not null, indexed => [sociable_type]
12
12
#
13
13
# Indexes
14
14
#
15
15
# index_social_profiles_on_sociable (sociable_type,sociable_id)
16
16
#
17
17
class SocialProfile < ApplicationRecord
18
+ include Suggestable
19
+ PROVIDERS = %w[ twitter linkedin bsky mastodon speakerdeck website ]
20
+
18
21
belongs_to :sociable , polymorphic : true
19
22
20
- enum :provider , {
21
- github : 0 ,
22
- twitter : 1 ,
23
- linkedin : 2 ,
24
- bsky : 3 ,
25
- mastadon : 4
26
- } ,
27
- suffix : true ,
28
- validate : { presence : true }
29
-
30
- before_save do
31
- self . value = self . class . normalize_value_for ( provider . to_sym , value )
23
+ enum :provider , PROVIDERS . index_by ( &:itself ) , validate : { presence : true }
24
+
25
+ after_initialize do
26
+ self . value = self . class . normalize_value_for ( provider . to_sym , value ) if provider . present?
32
27
end
33
28
29
+ validates :provider , presence : true
30
+ validates :value , presence : true , uniqueness : { scope : :provider }
31
+
32
+ scope :excluding_provider , -> ( provider ) { where . not ( provider :) }
33
+
34
34
# normalizes
35
- normalizes :github , with : -> ( value ) { value . gsub ( /^(?:https?:\/ \/ )?(?:www\. )?github\. com\/ / , "" ) . gsub ( /^@/ , "" ) }
36
35
normalizes :twitter , with : -> ( value ) { value . gsub ( %r{https?://(?:www\. )?(?:x\. com|twitter\. com)/} , "" ) . gsub ( /@/ , "" ) }
37
36
normalizes :linkedin , with : -> ( value ) { value . gsub ( %r{https?://(?:www\. )?(?:linkedin\. com/in)/} , "" ) }
38
- normalizes :bsky , with : -> ( value ) { value . gsub ( %r{https?://(?:www\. )?(?:[^\/ ]+\. com)/} , "" ) . gsub ( /@/ , "" ) }
37
+ normalizes :bsky , with : -> ( value ) { value . gsub ( %r{https?://(?:www\. )?(?:x\. com|bsky\. app/profile)/} , "" ) . gsub ( /@/ , "" ) }
38
+ normalizes :speakerdeck , with : -> ( value ) { value . gsub ( /^(?:https?:\/ \/ )?(?:www\. )?speakerdeck\. com\/ / , "" ) . gsub ( /^@/ , "" ) }
39
39
normalizes :mastodon , with : -> ( value ) {
40
40
return value if value &.match? ( URI ::DEFAULT_PARSER . make_regexp )
41
41
return "" unless value . count ( "@" ) == 2
@@ -44,4 +44,23 @@ class SocialProfile < ApplicationRecord
44
44
45
45
"https://#{ instance } /@#{ handle } "
46
46
}
47
+
48
+ def url
49
+ case provider . to_sym
50
+ when :twitter , :speakerdeck
51
+ "https://#{ provider } .com/#{ value } "
52
+ when :linkedin
53
+ "https://linkedin.com/in/#{ value } "
54
+ when :bsky
55
+ "https://bsky.app/profile/#{ value } "
56
+ else
57
+ value
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def managed_by? ( visiting_user )
64
+ sociable . managed_by? ( visiting_user )
65
+ end
47
66
end
0 commit comments