Save 37% off PRO during our Black Friday Sale! »

無理しないRails

1d1580fb0945b0ffadff18e28bead3c5?s=47 いも
March 08, 2017

 無理しないRails

社内Techカンファレンスで発表した資料です。

1d1580fb0945b0ffadff18e28bead3c5?s=128

いも

March 08, 2017
Tweet

Transcript

  1. Ҫຊେొ(.01&1"#0JOD ϖύϘςοΫΧϯϑΝϨϯε ແཧ͠ͳ͍3BJMT

  2. ΤϯδχΞ Ҫຊେొ!BEBSBQBUB ϗεςΟϯάࣄۀ෦ϩϦϙοϓνʔϜ IUUQTBEBSBQBUBDPN

  3. MPMJQPQSCͷϙΤϜͰ͢

  4. ࿩͢͜ͱ wMPMJQPQSCͱ͸ wMPMJQPQSC͕࡞ΒΕͨཧ༝ wMPMJQPQSCͷ޻෉ wMPMJQPQSCͷ͜Ε͔Β

  5. ࿩͢͜ͱ wMPMJQPQSCͱ͸ wMPMJQPQSC͕࡞ΒΕͨཧ༝ wMPMJQPQSCͷ޻෉ wMPMJQPQSCͷ͜Ε͔Β

  6. MPMJQPQKQ

  7. VTFSMPMJQPQKQ

  8. ೥ଓ͘ αʔϏε

  9. ϩϦϙοϓʂͷϑϩϯτ wMPMJQPQKQਃ͠ࠐΈϑΥʔϜͳͲ͕͋Δɻ1)1੡ wVTFSMPMJQPQKQϢʔβͷίϯτϩʔϧύωϧɻ1)1੡ ͲͪΒ΋ɺཪͰMPMJQPQSCͱݺ͹ΕΔ"1*ͱ௨৴͍ͯ͠Δɻ

  10. MPMJQPQSCͱ͸ wސ٬%#ٴͼϢʔβͷαʔό৘ใʹΞΫηε͢Δ"1* w3&45GVM wఆظతʹಈ͘όονͷ࣮ߦ΋ߦͳ͍ͬͯΔ wόον༻αʔόͱ"1*༻αʔόΛ෼͚ͯ༻ҙ͠ɺ྆ํʹMPMJQPQSCΛࡌ͍ͤͯΔ

  11. MPMJQPQSC֓ཁ w3BJMT wSBJMTBQJ͸࢖Θͣૉͷ3BJMTΛ࢖༻ w3VCP$PQʹΑΔίʔυղੳ wυΩϡϝϯτ͸BVUPEPDHFNͰੜ੒ w"DUJWF+PCʹEFMBZFE@KPCΛ࢖༻ w%#Λ̑ͭѻͬͯΔ

  12. MPMJQPQSC֓ཁ wϦιʔε਺ wϧʔςΟϯά਺ wϞσϧ࠷େߦ Ϟσϧʹ੹຿͕ूதͭͭ͋͠Δ  wίϯτϩʔϥ࠷େߦ wMJCʹΫϥε͕૿͖͑ͯͨͷͰݟ௚͕͠ඞཁ ద੾ͳσΟϨΫτϦ੾Γ෼͚ 

    wτϥϯβΫγϣϯܥ͸GBDBEFͰσΟϨΫτϦ੾ͬͯݟͨΓ
  13. ࿩͢͜ͱ wMPMJQPQSCͱ͸ wMPMJQPQSC͕࡞ΒΕͨཧ༝ wMPMJQPQSCͷ޻෉ wMPMJQPQSCͷ͜Ε͔Β

  14. ࠷ॳ͔Β"1*ͱͯ͠࡞ΒΕͨΘ͚Ͱ͸ͳ͍

  15. ͦͷੲͷϩϦϙοϓ

  16. ߏ੒ wϑϩϯτ ίϯύωɺਃࠐ ͱόοΫΤϯυʹ෼͔Ε͍ͯΔɻ wϑϩϯτMPMJQPQKQ VTFSMPMJQPQKQ ސ٬؅ཧશ෦QIQ wόοΫΤϯυMPMJQPQ"QJͪ͜Β΋QIQ wόοΫΤϯυͷ"1*ʹϩδοΫΛू໿ͤ͞ΔελΠϧͬΆ͔ͬͨ wMPMJQPQ"QJͷޙΖʹ͞Βʹ4FSWFS"QJͱ͍͏"1*͕͋Δ

    w4FSWFS"QJ͸ओʹϢʔβͷαʔόྖҬΛѻ͏"1*
  17. ౰࣌ͷߏ੒Λ؆ུԽͨ͠΋ͷ ཧ૝ MPMJQPQKQ VTFSMPMJQPQKQ ސ٬؅ཧ -PMJQPQ"1* 4FSWFS"1* αʔόαΠυ όοΫΤϯυ ϑϩϯτ

    Ϣʔβʹఏڙ͢ΔྖҬΛѻ͏ ɾ8&#αʔό ɾ.BJMαʔό ɾ.Z42-αʔόFUD Ϣʔβͷސ٬৘ใͳͲΛѻ͏ ɾΞΧ΢ϯτ৘ใ ɾݸਓ৘ใ ɾܖ໿৘ใFUD
  18. ՝୊ wͲ͜ͷ؀ڥ΋ϨΨγʔ wςετ΋΄΅ͳ͠ɺ໨ࢹ֬ೝ w࣮ࡍʹ͸ϑϩϯτʹ΋͕ͬͭΓϩδοΫ͕ॻ͔Ε͓ͯΓॲཧ͕ॏෳ͍ͯ͠Δ w"1*͕ޙൃͱ͍͏ͷ΋ཧ༝ w-PMJQPQ"QJΛແࢹͯ͠௚઀4FSWFS"QJୟ͍ͯͨΓ΋͢Δ w৽نͷॲཧΛͲ͜ʹॻ͍ͯ΋ۤ࿑ͯͨ͠ wطଘͷվम͸΋ͬͱۤ࿑ͨ͠

  19. ౰࣌ͷߏ੒Λ؆ུԽͨ͠΋ͷ ݱ࣮ MPMJQPQKQ VTFSMPMJQPQKQ ސ٬؅ཧ -PMJQPQ"1* 4FSWFS"1* αʔόαΠυ όοΫΤϯυ ϑϩϯτ

    Ϣʔβʹఏڙ͢ΔྖҬΛѻ͏ ɾ8&#αʔό ɾ.BJMαʔό ɾ.Z42-αʔόFUD Ϣʔβͷސ٬৘ใͳͲΛѻ͏ ɾΞΧ΢ϯτ৘ใ ɾݸਓ৘ใ ɾܖ໿৘ใFUD ςετ΄΅ແ͠ ςετແ͠ ςετແ͠ ςετແ͠ ϩδοΫ ϩδοΫ ϩδοΫ
  20. Ͳ͏͢Ε͹҆৺ͯ͠։ൃ͕Ͱ͖Δʁ

  21. ৭ʑग़͕ͨɺ͔ͬ͠Γணख͸ग़དྷͣ wॗʑͱطଘʹςετ௥Ճͯ͠ߦ͘ w౰࣌͸QIQͰςετͷ௥Ճ΋ҰےೄͰ͸͍͔ͳ͍ঢ়ଶͩͬͨ wࢥ͍੾ͬͯ৽نͰ࡞Γ௚͢ wςϯγϣϯ͸্͕Δ͚Ͳɺ͋·Γ࣌ؒΛ͔͚ΒΕͳ͍ɻ w-PMJQPQ"1*͕ͳΜͱ͔ςετॻ͚Δঢ়ଶͩͬͨͷͰɺͦͪΒʹد͍ͤͯͬͨ

  22. Ұํͦͷࠒ wMPMJQPQSCͱ͍͏ϦϙδτϦ͕͋ͬͨ w3BJMT੡ΞϓϦέʔγϣϯ w"DUJWF3FDPSEΛ࢖ͬͯαΫοͱސ٬৘ใΛݟ͍ͨͱ͍͏ئ͍͔Β࢈·Εͨ wͦͷଞɺαΫοͱόονॻ͍ͨΓͳͲʹ΋׆༻ wجຊతʹ3BJMTDPOTPMFͰԿ͔͢ΔҎ֎ͷ༻్͸ͳ͔ͬͨ

  23. ౰࣌ͷ3&"%.&NEͷίϛοτ

  24. MPMJQPQSCͷ੒௕ w$POTPMFͰศརʹѻ͏ͨΊʹɺΈΜͳ͕উखʹϩδοΫΛ௥Ճͯ͘͠ΕΔ wϢχοτςετ΋͔ܽͣ͞௥Ճ͞Ε͍ͯ͘ wͨͩͷศརπʔϧతଘࡏ͕ͩͬͨɺؾ͚ͮ͹ͲΜͲΜίΞ͕֦ு͞Ε͍ͯ͘

  25. MPMJQPQSCɺδϣϒαʔόʹͳΔ wఆظతʹॲཧ͢ΔόονΛ࡞Δඞཁ͕ग़͖ͯͨɻ wࠓ·Ͱ͸QIQ ςετίʔυͳ͠ Ͱॻ͍ͯͨɻ wखಈ֬ೝʹ΋ద੾ͳϨίʔυΛ࡞ͬͯ͋͛ͨΓͱ݁ߏେม wMPMJQPQSCͳΒSBLFUBTL͕࢖͑Δ wGBDUPSZ(JSMͰςετ༻Ϩίʔυ΋αΫοͱ࡞ΕΔ wͬͪ͜Ͱॻ͍ͨ΄͏͕͍͍ͷͰ͸ʁ

  26. QIQͱͷόον࣮૷ͱൺֱͯ͠ wςετͰಈ࡞͕อূͰ͖ΔͷͰɺಈ࡞֬ೝΑΓ΋ίʔυϨϏϡʔʹଟ࣌ؒ͘Λ ׂ͚ΔΑ͏ʹͳͬͨ w݁Ռɺ։ൃ଎౓͸্͕ͬͨ wϦϦʔεޙͷෆ۩߹͕શ͘ൃੜ͠ͳ͔ͬͨ ͍͍͜ͱ͔͠ͳ͔ͬͨ

  27. ͲΜͲΜ׆༻͢΂͖Ͱ͸ʁ

  28. MPMJQPQSC"1*αʔόʹͳΔ w৽نͰॻ͘ϩδοΫΛMPMJQPQSCʹҠߦͯ͠ϑϩϯτΛബ͍ͯ͘͘͠ wϩδοΫΛSCʹू໿͍͚ͯ͠͹֤؀ڥ͝ͱͷॏෳΛݮΒͤΔ w3BJMTͷͨΊςετ؀ڥ͸੔͓ͬͯΓ҆ఆͤ͞΍͍͢ wطଘͷ"1*ʹ͸ࠓޙ৽ن࣮૷͸ۃྗ͠ͳ͍ɻ͠͹Β͘ฒߦӡ༻ʹ͸ͳΔ wطଘ"1*ͷػೳ΋ॱ࣍MPMJQPQSCʹҠߦ͍ͯ͘͠

  29. ͜͏͢Δͧʂ MPMJQPQKQ VTFSMPMJQPQKQ ސ٬؅ཧ "1* 4FSWFS"1* αʔόαΠυ όοΫΤϯυ ϑϩϯτ Ϣʔβʹఏڙ͢ΔྖҬΛѻ͏

    ɾ8&#αʔό ɾ.BJMαʔό ɾ.Z42-αʔόFUD Ϣʔβͷސ٬৘ใͳͲΛѻ͏ ɾΞΧ΢ϯτ৘ใ ɾݸਓ৘ใ ɾܖ໿৘ใFUD ςετ΄΅ແ͠ ςετແ͠ ςετແ͠ ςετແ͠ MPMMJQPQSC
  30. MPMJQPQSC͕࡞ΒΕͨཧ༝·ͱΊ w"1*ϦχϡʔΞϧܭը͕͋ͬͨΘ͚Ͱ͸ͳ͘ɺطଘͷϦιʔεΛ׆༻͚ͨͩ͠ wʮ҆৺ͯ͠։ൃ͢Δʹ͸ʯͷམͱ͠ॴͱͯͪ͠ΐ͏ͲΑ͔ͬͨ w̍ͭͷػೳΛSCʹҠ২ɺ௥Ճ͸े෼࣮ݱՄೳͳ࿩ͳͷͰɺͲ͏΍Δ͔͕Πϝʔ δ͠΍͍͢ wʮ͜ͷਏ͍ͱ͜ΖɺSCʹ͍͚࣋ͬͯ͹ָʹͳΔͳɾɾʯͱಓے͕ݟ͑Δ͚ͩͰ ΋։ൃϞνϕʔγϣϯ͸ҡ࣋Ͱ͖ͨ

  31. ࿩͢͜ͱ wMPMJQPQSCͱ͸ wMPMJQPQSC͕࡞ΒΕͨཧ༝ wMPMJQPQSCͷ޻෉ wMPMJQPQSCͷ͜Ε͔Β

  32. MPMJQPQSC"1*ͷํ਑ wݫີʹํ਑ΛఆΊ͍ͯΔΘ͚Ͱ͸ͳ͍ wΦʔιυοΫεͳ3BJMTXBZɺ೉͍͜͠ͱ͸͠ͳ͍ wϩδοΫ͸ϞσϧʹɻDPODFSO DBMMCBDL WBMJEBUPSʹద੾ʹ෼ׂ wίϯτϩʔϥ͸$36%ΞΫγϣϯ͚ͩ࣋ͭ wHFNΛ׆༻͢Δ wݹ͍αʔϏε࢓༷ʹ͸ҾͬுΒΕͣɺͲ͏͋Δ΂͖͔Ͱߟ͑Δ w%))ͷߟ͑ํΛࢀߟʹ͢Δ͜ͱ͕ଟ͍

  33. ۃྗ3BJMTͷ࡞๏ʹ৐͔ͬΔ͜ͱͰ ։ൃʹඞཁͳ৘ใΛݮΒ͠ ෑډΛԼ͍͛ͨ

  34. ͕

  35. %#͕3BJMTͬΆ͘ͳ͍໰୊ wϢχʔΫ*%Λಠࣗʹੜ੒ׂͯ͠Γ౰ͯΔ࢓૊Έ ࠾൪ςʔϒϧ  w೔෇Λอ࣋͢ΔΧϥϜ͕l::::..%%zͷ7"3$)"3 w໊લ͔ΒԿ΋఻ΘΒͳ͍ΧϥϜ͕ଟ͍ɻ௨শFUDΧϥϜ wͦ΋ͦ΋ෳ਺%# wͳͲͳͲɾɾ ͜ΕΒΛࠓ͔Βม͑Δ͜ͱ͸೉͍͠

  36. 3BJMTͬΆ͘ͳ͍ͱ͜ΖΛ 3BJMTͷ࢓૊ΈͰٵऩͯ͠ 3BJMTͬΆ͘ॻ͚ΔΑ͏ʹ͢Δ

  37. ΧϥϜ͸BMJBT@BUUSJCVUFͰ͓खܰʹରԠ͢Δ alias_attribute :feedback_message, :etc8 # ਓؒʹΘ͔Γ΍͘͢ alias_attribute :updated_at, :update_date #

    railsͬΆ͘
  38. ಠࣗϧʔϧ͸$PODFSOʹ·ͱΊͯΈΔ module LegacyDateFormattable extend ActiveSupport::Concern included do class << self

    attr_reader :legacy_dates def legacy_dates=(dates) @legacy_dates = dates define_methods_for_generize_date end def define_methods_for_generize_date # ΧϥϜ໊Λ্ॻ͖ͯ͠DateΦϒδΣΫτฦ͢ϝιουΛੜ੒ end end end end class Contract < ActiveRecord::Base include LegacyDateFormattable self.legacy_dates = %i( start_date end_date ) end w ྫ͑͹ಠࣗͷ೔෇ΧϥϜ͸ɺ4USJOH%BUFͰ ૬ޓʹม׵͢Δ$PDFSOϞδϡʔϧΛ࣮૷͍ͯ͠ Δ w ࠾൪ॲཧͳͲ΋BQQNPEFMTDPODFSOTԼʹϞ δϡʔϧΛ௥Ճ͍ͯ͠Δ w ϞδϡʔϧΛ௥Ճ͓͚ͯ͠͹ɺಠࣗϧʔϧΛ͋· Γؾʹͤͣී௨ͷϞσϧͱͯ͠;Δ·͑Δ w ΍΍ϝλϓϩʹͳΓ͕ͪ
  39. w΋ͱ΋ͱ࢖ͬͯͨϝΠϯͷސ٬%#Λ௨ৗͷ%#ͱͯ͠ߟ͑Δ wͦͷଞ%#ͷϞσϧͱ઀ଓ৘ใΛͲ͔͜ʹఆٛ͠ͳ͍ͱ͍͚ͳ͍ wϞσϧͱ઀ଓ৘ใͱεΩʔϚΛద੾ͳҐஔʹ഑ஔͯ͋͛͠Δ wϞσϧ͸BQQNPEFMTIPHF@ECCBTFSCʹఆٛ w઀ଓ৘ใ͸EBUBCBTFZNMͱಉ͡֊૚ʹIPHF@EBUBCBTFZNMΛఆٛ wεΩʔϚ͸ECPUIFSTIPHF@ECTUSVDUVSFTRMΛஔ͘ wҰׅͰηοτΞοϓͰ͖ΔλεΫΛ࡞Δ ෳ਺%#ͷ؅ཧ

  40. Ϟσϧͷఆٛ class Hogedb::Base < ActiveRecord::Base self.abstract_class = true establish_connection Lolipop::Database.load_configuration(:hoge_db)[Rails.env.to_s]

    end w Ҿ਺ͰΑ͠ͳʹ઀ଓ৘ใͷ:".-Λϩʔυͯ͠઀ଓ͢Δ w ֤ςʔϒϧͷϞσϧ͸#BTFΛܧঝ࣮ͯ͠૷͢Δ
  41. ઀ଓ৘ใͱεΩʔϚΛ഑ஔ config ├── application.rb ├── environment.rb ├── environments/ ├── database.yml

    ├── hogedb_database.yml ├── fugadb_database.yml ├── foodb_database.yml ├── bardb_database.yml ├── routes.rb └── secrets.yml db ├── others │ ├── hogedb │ │ └── structure.sql │ ├── fugadb │ │ └── structure.sql │ ├── foodb │ │ └── structure.sql │ └── bardb │ ├── seeds.rb │ └── structure.sql ├── seeds.rb └── structure.sql
  42. PUIFS@ECͷηοτΞοϓλεΫΛ࡞Δ other_databases = %w(hogedb fugadb) other_databases.each do |db| current_namespace =

    namespace db.to_sym do task :load_config do end desc "Creates the #{db}" task :create => [:load_config] do end desc "Drops the #{db}" task :drop => [:load_config] do end namespace :structure do task :load => [:create, :environment, :load_config] do end end desc "Creates the #{db} and load schema" task :setup => ["#{db}:structure:load"] end end جຊ͸3BJMTͷ%BUBCBTFSBLFΛࢀߟʹ͢Δ
  43. ෳ਺%#ΛҰׅηοτΞοϓ namespace :multi_db do @databases = %w(hogedb fugadb foodb) desc

    'Sets up all databases' task :setup do @databases.each { |database| Rake::Task["#{database}:setup"].invoke } end desc 'Creates all databases' task :create do @databases.each { |database| Rake::Task["#{database}:create"].invoke } end desc 'Drops all databases' task :drop do @databases.each { |database| Rake::Task["#{database}:drop"].invoke } end end NVMUJ@ECTFUVQͰશ%#͕࡞ΒΕγʔυ஋͕ྲྀ͠ࠐ·ΕΔ
  44. 3BJMTʹͳ͖ͬͯͨ

  45. ݄೔͸ྲྀΕ wSCΛ։ൃ͍ͯ͠Δؒʹϑϩϯτ؀ڥ΋վળ͞Ε͍ͯͬͨ wQIQͷόʔδϣϯ্͕͕ͬͨ wͲ͜΋ςετ͕ॻ͚Δঢ়ଶ STQFD QIQVOJU UBQF MPMJQPQSC͚͕ͩ҆ఆͨ͠؀ڥͱ͍͏ঢ়ଶͰ͸ͳ͘ͳͬͨͷͰ ։ൃͷબ୒ࢶ͕૿͖͑ͯͨ

  46. ͦΕͰ΋"1*ϑΝʔετ wϩδοΫΛू໿͢Δͱ͍͏͜ͱʹՁ஋͕͋Δ wྫ֎Λআ͖ɺϑϩϯτʹॻ͘͜ͱ͸ආ͚͍ͯ͘ w௚઀%#ΛݺΜͰϨεϙϯεΛૣ͍ͨ͘͠ͳͲ ϑϩϯτʹ͕ͬͭΓॻ͘৔߹͸ɺͦΕͰੜ·ΕΔՁ஋Λ͔ͬ͠Γۛຯ͢Δɻ ٸ͔͗ͩΒϑϩϯτʹʙ͸কདྷతʹอकͷ೉қ౓্͕͕Γ͕ͪɻ ͨͱ͑਺ߦͰ΋ɺʮͳΜͰ͜͜ʹʁʯͷٙ໰Λ෷১͢Δௐࠪ͸݁ߏେมɻ

  47. ࿩͢͜ͱ wMPMJQPQSCͱ͸ wMPMJQPQSC͕࡞ΒΕͨཧ༝ wMPMJQPQSCͷ޻෉ wMPMJQPQSCͷ͜Ε͔Β

  48. Ҿ͖ଓ͖"1*Խ wϩδοΫΛSCʹҠߦ͍͖ͯ͠ɺϑϩϯτΛܰྔԽ wԿॲ͔ͷλΠϛϯάͰϑϩϯτΛ৽͘͠࡞Γ௚͢ɻ wQIQͰ΋KTͰ΋ͳΜͰ΋͍͍ɻબఆͷ෯͕޿͕Δɻ wࠓ΍ΔͳΒ41"

  49. ׬શͳ3BJMTԽ wٯʹϑϩϯτͱόοΫΤϯυΛ͚ͬͭͯ͘͠·͏ wMPMJQPQSCʹ$POUSPMMFSͱ7JFX΋௥Ճ͍ͯ͘͠ w֤ϑϩϯτΛ໊લۭؒͰ෼͚ͯશ෦SCʹ࣮૷͢Δ w8&#"1*Ͱ΍ΓͱΓ͢ΔΑΓॲཧ଎౓͕଎͘ͳΔ͔΋ w3BJMTͱӡ໋Λڞʹ͢Δ֮ޛ

  50. ׬શ3BJMTԽ αʔόαΠυ ϑϩϯτ MPMJQPQKQ MPMJQPQSC VTFSMPMJQPQKQ MPMJQPQSC ސ٬؅ཧ MPMJQPQSC 4FSWFS"1*

    Ϣʔβʹఏڙ͢ΔྖҬΛѻ͏ ɾ8&#αʔό ɾ.BJMαʔό ɾ.Z42-αʔόFUD
  51. Ͳ͕͍͍͔ͬͪ͸Θ͔Βͳ͍ wઌͷ͜ͱ͸Θ͔Βͳ͍ͷͰɾɾ wͦΕ͸ະདྷͰߟ͑·͠ΐ͏ wͲͪΒͰ΋ରԠͰ͖ΔΑ͏ʹɺίΞΛॆ࣮͍ͤͯ͘͞ wϩϦϙοϓʂͷػೳMPMJQPQSCʹͳΔ·Ͱ͍͚࣋ͬͯΕ͹ͳΜͰ΋Ͱ͖Δ

  52. ण໋ΛԆ͹ͨ͢Ίʹ w࢖͍қ͍ɺཧղ͠қ͍ઃܭʹ͢Δ wMPMJQPQSCͳΒ3BJMT8BZɺڻ͖࠷খͷݪଇ wಓΛ֎ΕΔͱɺগͮͭ͠໘౗ͩͱײ࢝͡ΊΔ w໘౗͕ੵΈॏͳΔͱɺ৮Γͨ͘ͳ͘ͳΓ࢝ΊΔ wʮ৽͘͠࡞Γ௚ͨ͠΄͏͕͍͍Μ͡ΌͶʂʯͷ࠶དྷ wΈΜͳͰίʔυϨϏϡʔͰ༧๷͠Α͏ʂ

  53. ͓ΘΓ