Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Action Cableを使って 分報機能を実装しています

Action Cableを使って 分報機能を実装しています

This is the presentation I gave at the "First LT Meeting #2" for the students on May 9, 2020.

Kohei Takahashi

May 09, 2020
Tweet

More Decks by Kohei Takahashi

Other Decks in Programming

Transcript

  1.  ࣗݾ঺հ  "DUJPO$BCMFͷੈք؍  ͲͷΑ͏ʹ࣮૷͍ͯ͠Δͷ͔  ·ͱΊ  ࢀߟαΠτ

    ˞Ͱ͖Δ͚ͩਖ਼֬ͳ಺༰Λ఻͑ΔΑ͏ʹ৺͕͚ͯ·͕͢ɺؒҧͬͨ಺༰Λ࿩ͯͨ͠Β͍͢·ͤΜ ˞ͦͷࡍ͸ڭ͑ͯͩ͘͞Δͱେม༗೉͍Ͱ͢ ͜ͷൃදͷ಺༰
  2. ෼ใϖʔδΛ։͍ͨ࣌ͷॲཧͷྲྀΕ 7VFίϯϙʔωϯτ UJNFMJOFT@DIBOOFMWVF UJNFMJOFWVF 7VFKTଆ 3BJMTଆ BQQDIBOOFMT DIBOOFMSC DPOOFDUJPOSC BQQMJDBUJPO@DBCMF

    UJNFMJOFT@DIBOOFMSC ᶆαϒεΫϥΠϒ͞ΕͨΒɺ աڈͷ෼ใҰཡͷσʔλΛૹΔ ᶃίϯϙʔωϯτ͕DSFBUF͞Εͨ࣌ʹ 8FC4PDLFUίωΫγϣϯΛ࡞Ζ͏ͱ͢Δ ᶄDVSSFOU@VTFSͳΒ ίωΫγϣϯΛཱ֬͢Δ ᶅίωΫγϣϯཱ͕֬͞ΕͨΒ αϒεΫϥΠϒ͢Δ
  3. 8FC4PDLFUίωΫγϣϯͷཱ֬ʹؔ͢Δॲཧ Λهड़͍ͯ͠·͢ɻ ͜͜Ͱ͸ɺJEFOUJGJFE@CZͰ8FC4PDLFUίω ΫγϣϯʹJEΛ༩͍͑ͯ·͢ɻ ͜͜Ͱ͸ɺDVSSFOU@VTFSΛίωΫγϣϯͷJE ʹ͍ͯ͠·͢ɻ DPPLJF͔ΒDVSSFOU@VTFSͷ৘ใΛಡΈऔͬ ͍ͯ·͢ɻ΋͠ɺDPPLJFʹDVSSFOU@VTFSͷ ৘ใ͕ͳ͚Ε͹ɺίωΫγϣϯΛཱ֬͠·ͤ Μɻ

    DPOOFDUJPOSCΛݟ͍ͯ͘ ۩ମతͳίʔυ͕ཉ͍͠ module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user end private def find_verified_user if verified_user = User.find_by(id: store["user_id"]) verified_user else reject_unauthorized_connection end end def store cookies.encrypted[Rails.application.config.session_options[:key]] end end end
  4. "DUJPO$BCMFͷDIBOOFMʹ͓͚Δ DPOUSPMMFSͷ໾ׂΛ୲͍·͢ɻ ͦͷͨΊɺ$36%ͷॲཧΛهड़ͯ͠· ͢ɻ σʔλΛϒϩʔυΩϟετ͢Δ͜ͱͰɺ νϟωϧʹσʔλΛૹΓ·͢ɻ ·ͨɺαϒεΫϥΠϒͨ࣌͠΍ɺαϒε ΫϥΠϒ͕ऴΘͬͨ࣌ͷॲཧΛॻ͖· ͢ɻ ͜͜Ͱ͸ɺαϒεΫϥΠϒͨ࣌͠ʹɺա

    ڈͷ෼ใҰཡΛૹΔΑ͏ʹ͍ͯ͠·͢ɻ UJNFMJOFT@DIBOOFMSCΛݟ͍ͯ͘ ۩ମతͳίʔυ͕ཉ͍͠ class TimelinesChannel < ApplicationCable::Channel include Rails.application.routes.url_helpers def subscribed stream_from "timelines_channel" timelines = Timeline.order(created_at: :asc) transmit({ event: "timelines", current_user: format_current_user, timelines: format_timelines(timelines) }) end def unsubscribed # Any cleanup needed when channel is unsubscribed end def create_timeline(data) @timeline = Timeline.create!(user_id: current_user.id, description: data["description"]) ActionCable.server.broadcast "timelines_channel", { event: "create_timeline", timeline: format_timeline(@timeline) } end def update_timeline(data) @timeline = Timeline.find_by(id: data["id"]) @timeline.update(description: data["description"]) ActionCable.server.broadcast "timelines_channel", { event: "update_timeline", timeline: format_timeline(@timeline) } end def delete_timeline(data) @timeline = Timeline.find_by(id: data["id"]) @timeline.destroy ActionCable.server.broadcast "timelines_channel", { event: "delete_timeline", timeline: format_timeline(@timeline) } end end
  5. ෼͔Γ΍͍͢Α͏ʹҰ෦ൈਮͱɺվมΛߦ͍ͬͯ ·͢ɻ ͜͜ʹɺϑϩϯτΤϯυଆͷUJNFMJOF@DIBOOFM ʹؔ͢Δ৘ใ͕·ͱ·͍ͬͯ·͢ CSPBEDBTU͞Εͨσʔλ͸\BDUJPODSFBUF  UJNFMJOF!UJNFMJOF^ͳͲͷܗͰૹΔΑ͏ʹ͠ ͍ͯ·͢ɻ ͦ͜Ͱɺड͚औͬͨσʔλͷBDUJPO͕ͳΜͳͷ ͔ͰɺॲཧΛม͑ΔΑ͏ʹ͍ͯ͠·͢ɻ

    UJNFMJOFTDIBOOFMWVFΛݟ͍ͯ͘ this.timelinesChannel = this.$cable.subscriptions.create("TimelinesChannel", { connected: () => { console.log('connected successfully') }, disconnected: () => { }, received: (data) => { switch (data.event) { case 'timelines': data.timelines.forEach((timeline) => { this.timelines.unshift(timeline) }) break case 'create_timeline': this.timelines.unshift(data.timeline) break case 'update_timeline': this.timelines.forEach((timeline) => { if (timeline.id === data.timeline.id) { timeline.description = data.timeline.description } }) break case 'delete_timeline': this.timelines.forEach((timeline, i) => { if (timeline.id === data.timeline.id) { this.timelines.splice(i, 1) } }) break } } })