diff --git a/app/models/speaker.rb b/app/models/speaker.rb index 2d28271e..99f3cdfc 100644 --- a/app/models/speaker.rb +++ b/app/models/speaker.rb @@ -7,7 +7,7 @@ # bio :text default(""), not null # bsky :string default(""), not null # bsky_metadata :json not null -# github :string default(""), not null +# github :string default(""), not null, indexed # github_metadata :json not null # linkedin :string default(""), not null # mastodon :string default(""), not null @@ -26,6 +26,7 @@ # Indexes # # index_speakers_on_canonical_id (canonical_id) +# index_speakers_on_github (github) UNIQUE WHERE github IS NOT NULL AND github != '' # index_speakers_on_name (name) # index_speakers_on_slug (slug) UNIQUE # @@ -66,7 +67,7 @@ class Speaker < ApplicationRecord # validations validates :canonical, exclusion: {in: ->(speaker) { [speaker] }, message: "can't be itself"} - validates :name, presence: true, uniqueness: {case_sensitive: false} + validates :github, uniqueness: {case_sensitive: false}, allow_blank: true # scope scope :with_talks, -> { where.not(talks_count: 0) } diff --git a/data/speakers.yml b/data/speakers.yml index b388ad4c..bac8afcf 100644 --- a/data/speakers.yml +++ b/data/speakers.yml @@ -1265,15 +1265,6 @@ website: "" slug: andres canonical_slug: -- name: Andrew - twitter: teabass - github: andrew - bio: - "Working on mapping the world of open source software @ecosyste-ms and empowering - developers with @octobox " - website: https://nesbitt.io - slug: andrew - canonical_slug: - name: Andrew Atkinson twitter: andatki github: andyatkinson @@ -1406,15 +1397,6 @@ website: "" slug: andrew-neely canonical_slug: -- name: Andrew Nesbitt - twitter: teabass - github: andrew - bio: - "Working on mapping the world of open source software @ecosyste-ms and empowering - developers with @octobox " - website: https://nesbitt.io/ - slug: andrew-nesbitt - canonical_slug: - name: Andrew Nordman twitter: "" github: cadwallion @@ -1429,15 +1411,6 @@ website: "" slug: andrew-novoselac canonical_slug: -- name: Andrew Radev - twitter: AndrewRadev - github: AndrewRadev - bio: - "\"Nooooo, you can't keep solving your problems by writing Vim plugins, use - a real programming language\"\r\n\r\nHaha vimscript go brrrrr" - website: https://andrewra.dev - slug: andrew-radev - canonical_slug: - name: Andrew Shafer twitter: "" github: "" @@ -1563,15 +1536,6 @@ website: "" slug: andy-delcambre canonical_slug: -- name: Andy Glass - twitter: "" - github: Andrewglass1 - bio: "" - website: andyglass.net - slug: andy-glass - canonical_slug: -- name: Andy Lindeman - twitter: "" github: alindeman bio: "" website: https://andylindeman.com/ @@ -7009,13 +6973,6 @@ website: https://sue445.hatenablog.com/ slug: go-sueyoshi canonical_slug: -- name: Godfrey - twitter: "" - github: chancancode - bio: "" - website: http://about.me/godfreychan - slug: godfrey - canonical_slug: - name: Godfrey Chan twitter: "" github: chancancode @@ -7665,15 +7622,6 @@ website: "" slug: hiroyuki-sano canonical_slug: -- name: Hitoshi Hasumi - twitter: hasumikin - github: hasumikin - bio: - "Creator of PicoRuby and PRK Firmware.\r\nMaintainer of ruby/irb, ruby/reline, - and mrubyc/mrubyc." - website: https://hasumikin.com/about - slug: hitoshi-hasumi - canonical_slug: - name: Hiếu Nguyễn twitter: "" github: hieuk09 @@ -10607,13 +10555,6 @@ website: https://ideia.me slug: jonatas-davi-paganini canonical_slug: -- name: Jônatas Paganini - twitter: jonatasdp - github: jonatas - bio: "@timescale" - website: https://ideia.me - slug: jonatas-paganini - canonical_slug: - name: KJ Tsanaktsidis twitter: KJTsanaktidis github: KJTsanaktsidis @@ -12327,13 +12268,6 @@ website: http://mensfeld.pl slug: maciej-mensfeld canonical_slug: -- name: Maciej Rzasa - twitter: "" - github: mrzasa - bio: "" - website: "" - slug: maciek-rzasa - canonical_slug: - name: Maciej Rząsa twitter: "" github: mrzasa @@ -12949,15 +12883,6 @@ website: "" slug: mary-lee canonical_slug: -- name: Masafumi Okura - twitter: okuramasafumi - github: okuramasafumi - bio: - "Rails developer. ❤️ Ruby, Vim\nThe chief organizer of Kaigi on Rails: @kaigionrails - \nThe organizer of @grow-rb and @entaku-rb" - website: https://okuramasafumi.com - slug: masafumi-okura - canonical_slug: - name: Masahiro Ihara twitter: "" github: ihara2525 @@ -15234,15 +15159,6 @@ website: "" slug: olga-scott canonical_slug: -- name: Oliver Lacan - twitter: olivierlacan - github: olivierlacan - bio: - "Shields.io creator, @rails & @ruby contributor, built Code School, maintaining - @keepachangelog. " - website: http://olivierlacan.com - slug: oliver-lacan - canonical_slug: - name: Oliver Sanford twitter: "" github: oliverjesse @@ -18923,13 +18839,6 @@ website: "" slug: surbhi-gupta canonical_slug: -- name: Sutou Kouhei - twitter: "" - github: kou - bio: "" - website: https://www.clear-code.com/ - slug: sutou-kouhei - canonical_slug: - name: Suzan Bond twitter: "" github: suzanbond @@ -20779,13 +20688,6 @@ website: https://yechiel.me slug: yechiel-kalmenson canonical_slug: -- name: Yehuda - twitter: wycats - github: wycats - bio: "" - website: http://yehudakatz.com - slug: yehuda - canonical_slug: - name: Yehuda Katz twitter: wycats github: wycats @@ -21209,13 +21111,6 @@ website: "" slug: hatsu38 canonical_slug: -- name: hogelog - twitter: "" - github: hogelog - bio: "" - website: "" - slug: hogelog - canonical_slug: - name: i110 twitter: "" github: "" diff --git a/db/migrate/20250128070756_add_unique_index_on_github_in_speaker.rb b/db/migrate/20250128070756_add_unique_index_on_github_in_speaker.rb new file mode 100644 index 00000000..ab0bdb71 --- /dev/null +++ b/db/migrate/20250128070756_add_unique_index_on_github_in_speaker.rb @@ -0,0 +1,30 @@ +class AddUniqueIndexOnGitHubInSpeaker < ActiveRecord::Migration[8.0] + def up + # remove duplicate with no talks + Speaker.group(:github).having("count(*) > 1").pluck(:github).each do |github| + Speaker.where(github: github, talks_count: 0).update_all(github: "") + end + + # some speaker with a canonical speaker still have talks attached to them let's reasign them + Speaker.not_canonical.where.not(talks_count: 0).each do |speaker| + speaker.assign_canonical_speaker!(canonical_speaker: speaker.canonical) + end + + # fix one by one + Speaker.find_by(name: "Andrew").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(name: "Andrew Nesbitt")) + Speaker.find_by(name: "HASUMI Hitoshi").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(name: "Hitoshi Hasumi")) + Speaker.find_by(name: "hogelog").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(name: "Sunao Hogelog Komuro")) + Speaker.find_by(name: "Jônatas Paganini").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(name: "Jônatas Davi Paganini")) + Speaker.find_by(name: "Sutou Kouhei").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(name: "Kouhei Sutou")) + Speaker.find_by(slug: "maciek-rzasa").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(slug: "maciej-rzasa")) + Speaker.find_by(slug: "mario-alberto-chavez").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(slug: "mario-chavez")) + Speaker.find_by(slug: "enrique-morellon").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(slug: "enrique-mogollan")) + Speaker.find_by(slug: "masafumi-okura").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(slug: "okura-masafumi")) + Speaker.find_by(slug: "oliver-lacan").assign_canonical_speaker!(canonical_speaker: Speaker.find_by(slug: "olivier-lacan")) + add_index :speakers, :github, unique: true, where: "github IS NOT NULL AND github != ''" + end + + def down + remove_index :speakers, :github + end +end diff --git a/db/schema.rb b/db/schema.rb index c11a545f..4a26cc2f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -162,6 +162,7 @@ t.json "bsky_metadata", default: {}, null: false t.json "github_metadata", default: {}, null: false t.index ["canonical_id"], name: "index_speakers_on_canonical_id" + t.index ["github"], name: "index_speakers_on_github", unique: true, where: "github IS NOT NULL AND github != ''" t.index ["name"], name: "index_speakers_on_name" t.index ["slug"], name: "index_speakers_on_slug", unique: true end diff --git a/test/fixtures/speakers.yml b/test/fixtures/speakers.yml index 4af94988..f081dfa5 100644 --- a/test/fixtures/speakers.yml +++ b/test/fixtures/speakers.yml @@ -7,7 +7,7 @@ # bio :text default(""), not null # bsky :string default(""), not null # bsky_metadata :json not null -# github :string default(""), not null +# github :string default(""), not null, indexed # github_metadata :json not null # linkedin :string default(""), not null # mastodon :string default(""), not null @@ -26,6 +26,7 @@ # Indexes # # index_speakers_on_canonical_id (canonical_id) +# index_speakers_on_github (github) UNIQUE WHERE github IS NOT NULL AND github != '' # index_speakers_on_name (name) # index_speakers_on_slug (slug) UNIQUE #