大掃除 on Rails @Otemachi.rb #12

大掃除 on Rails @Otemachi.rb #12

586a2d464eed3c7e5dd809d6fe0269d7?s=128

YABOO JAPAN

January 12, 2019
Tweet

Transcript

  1. େ૟আ on Rails @yaboojp on Otemachi.rb #12 2018-12-12

  2. Self.inspect • Name: େ༅ Ӭ • Twitter: @yaboojp • Jobs:

    • 22Inc. Co-Founder & CTO @த໨ࠇ • NTTdata @ங஍ʙ๛ऱ • Location: ژ౎ -> ౦ژ • Favorites: Ϗʔϧ, Իָ, JALϚΠϨʔδमߦૐ
  3. None
  4. ελϯϓε.versions • Rails 5.0.7 • Ruby 2.3.4 • 2013/11/22~ ໿5೥αʔϏεӡ༻

  5. ࢣ૸Ͱ͢Ͷ

  6. େ૟আ͠·͔ͨ͠ʁ

  7. ίʔυͷେ૟আ͸ʁ

  8. ϦϑΝΫλʹ΋৭ʑελΠϧ ͋Δ͕ख෇͔ͣʹͳΓ͕ͪ

  9. େ૟আϦϑΝΫλ ͱ͍͏ ελΠϧ

  10. ※ ஫ҙ ɹͨͩ͠ɺ͓ૣΊʹ ϛεΔͱ஍ࠈͷ͓ਖ਼݄ʹͳΓ·͢

  11. ͪͳΈʹ • Spring Cleaning • ΞϝϦΧͰ͸େ૟আ͸य़ʹ΍Δ΋ͷ • Year-end Cleaning ͱ͸ݴΘͳ͍

  12. None
  13. ΁ʔ

  14. େ૟আ.targets • db/migrate • routes.rb • ࢖ΘΕͳ͍ػೳ

  15. db/migrate > େ૟আ.perform

  16. Gem 'squasher' • db/migrateͷϑΝΠϧΛ͍͍ײ͡ʹ͓·ͱΊͯ • rails db:migrate:reset͢Δͨͼʹ૸Δແବͳ migration • ࣮͸ڈ೥΋΍ͬͯΔ

    • db/migrate ໿200ϑΝΠϧ
  17. Before -> After # After $ bundle exec squasher 2018/12/31

    -m 5.0 $ ls -1 db/migrate 20181127022217_init_schema.rb <- 2ϑΝΠϧ 20181210165307_squasher_clean.rb # Before $ ls -1 db/migrate 20180102112652_init_schema.rb 20180109022927_***********.rb 20180110024712_***********.rb 20180111000100_***********.rb ɹɹɹɾ ɹɹɹɾ <- ໿200ϑΝΠϧ ɹɹɹɾ 20181119063850_***********.rb 20181120002536_***********.rb 20181127022217_***********.rb
  18. routes.rb > େ૟আ.perform

  19. routes.rb ෼ׂ • Ϣʔβ޲͚ ΞϓϦAPI • Ϣʔβ޲͚ ΞϓϦWebView • Ϣʔβ޲͚

    LP • ΫϥΠΞϯτ޲͚ ؅ཧϖʔδ • ࿈ܞاۀ޲͚ API • ͦͷଞʢWebHook, HelthCheckͳͲʣ
  20. Before Rails.application.routes.draw do #-------------------------------- # # Gem # #-------------------------------- #

    Doorkeeper - Admin༻ scope 'agency/admin' do use_doorkeeper scope: 'oauth2' do skip_controllers :authorizations, :tokens controllers applications: 'agency/admin/doorkeeper_applications' end end # Ckeditor mount Ckeditor::Engine => '/ckeditor' # Sidekiq authenticate :agent, lambda {|a| a.role_is_high? } do mount Sidekiq::Web => '/sidekiq' end # LetterOpenerWeb if Rails.env.development? || Rails.env.staging? mount LetterOpenerWeb::Engine, at: "/letter_opener" end # ళฮLP ࢑ఆϦμΠϨΫτ λΠϛϯάݟͯফ͢ get '/shops/22406', to: redirect(subdomain: "c", path: "/shops/22406"), constraints: {subdomain: ''} get '/shops/52640', to: redirect(subdomain: "c", path: "/shops/52640"), constraints: {subdomain: 'b'} get '/shops/38305', to: redirect(subdomain: "c", path: "/shops/38305"), constraints: {subdomain: 'b'} get '/shops/48117', to: redirect(subdomain: "c", path: "/shops/48117"), constraints: {subdomain: 'b'} get '/shops/1234', to: redirect(subdomain: "c", path: "/shops/1234"), constraints: {subdomain: 'b'} get '/shops/88022', to: redirect(subdomain: "c", path: "/shops/88022"), constraints: {subdomain: 'b'} #-------------------------------- # # Webϖʔδ # #-------------------------------- constraints subdomain: '' do # ------- αʔϏεαΠτҠߦޙʹ࡟আ ------- root to: "pages/root#top" get '/features', to: "pages/root#features" get '/price', to: "pages/root#price" get '/faq', to: "pages/root#faq", as: :faq get '/contact', to: "pages/root#contact" post '/contact', to: "pages/root#contact" post '/confirm', to: "pages/root#confirm" post 'create', to: "pages/root#create" get '/thanks', to: "pages/root#thanks" get '/law', to: "pages/root#law" get "/app", to: "pages/root#app", as: :site_app # ࣄྫ get '/case', to: "pages/case#index" get '/case/category/:category', to: "pages/case#category" get '/case/:identifer', to: "pages/case#show" # χϡʔε get '/news', to: "pages/news#index" get '/news/category/:category', to: "pages/news#category" get '/news/:identifer', to: "pages/news#show" # ------- αʔϏεαΠτҠߦઌʹઃఆҠ؅ ------- # چϓϨεϦϦʔε get "/press", to: redirect(URI.escape("/news/category/ϓϨεϦϦʔε"), status: 301) get "/press/:identifer", to: redirect{ |params, request| "/news/#{params[:identifer]}?#{request.query_string}"} # چΞϓϦϖʔδURL get "/download", to: redirect("/app", status: 301) get "/dl", to: redirect("/app", status: 301) # App get "/dp", to: redirect(subdomain: "c", path: "/dp"), as: :r_dp get "/ds/*data", to: redirect(subdomain: "c", path: "/ds/%{data}"), as: :r_ds get "/DS/*data", to: redirect(subdomain: "c", path: "/DS/%{data}"), as: :r_ds2 get "/dt", to: redirect(subdomain: "c", path: "/dt"), as: :r_dt get "/db", to: redirect(subdomain: "c", path: "/db"), as: :r_db get "/launch", to: redirect(subdomain: "c", path: "/launch"), as: :r_launch # UserPromotion get "/user_promotions/*id", to: redirect(subdomain: "c", path: "/promotions/%{id}"), as: :r_pages_promotion_1 get "/app/user/user_promotions/*id", to: redirect(subdomain: "c", path: "/promotions/%{id}"), as: :r_pages_promotion_2 # FAQ ϦμΠϨΫτ get '/shops/documents', to: redirect(subdomain: "c", path: "/faqs/doc"), as: :r_shops_documents get '/shops/faq', to: redirect(subdomain: "c", path: "/faqs?type=shop"), as: :r_shops_faq get '/shops/faq/*id', to: redirect(subdomain: "c", path: "/faqs/%{id}"), as: :r_shops_faq_show get '/agency/faq', to: redirect(subdomain: "c", path: "/faqs?type=agency"), as: :r_agency_faq get '/agency/faq/*id', to: redirect(subdomain: "c", path: "/faqs/%{id}"), as: :r_agency_faq_show # ؅ཧը໘ͷ࢑ఆϦμΠϨΫτ get "/agency/*path", to: redirect(subdomain: "b", path: "/agency/%{path}") get "/agency", to: redirect(subdomain: "b", path: "/agency") get "/shops/*path", to: redirect(subdomain: "b", path: "/shops/%{path}") get "/shops", to: redirect(subdomain: "b", path: "/shops") get "/staffs/*path", to: redirect(subdomain: "b", path: "/staffs/%{path}") get "/staffs", to: redirect(subdomain: "b", path: "/staffs") get "/operation/*path", to: redirect(subdomain: "b", path: "/operation/%{path}") get "/operation", to: redirect(subdomain: "b", path: "/operation") get "/shop_app_ios_version", to: redirect(subdomain: "s", path: "/shop_app_ios_version") # ΞʔςΟετελϯϓ get '/app/user/events/*id/stamp_url', to: redirect(subdomain: "user", path: "/app/user/events/%{id}/stamp_url") # LP ࢑ఆϦμΠϨΫτ get '/lp/oscar', to: redirect("https://22inc.jp/lp/oscar/") # چ ن໿ྨͷϦϯΫ get "/users/term", to: redirect(subdomain: "c", path: "/policies/term"), as: :r_policies_term get "/users/privacy", to: redirect(subdomain: "c", path: "/policies/privacy"), as: :r_policies_privacy get "/users/privacy2", to: redirect(subdomain: "c", path: "/policies/privacy2"), as: :r_policies_privacy2 get "/users/personal", to: redirect(subdomain: "c", path: "/policies/personal"), as: :r_policies_personal get "/users/personal2", to: redirect(subdomain: "c", path: "/policies/personal2"), as: :r_policies_personal2 end # ------- αʔϏεαΠτҠߦઌʹઃఆҠ؅ ------- # FAQ ϦμΠϨΫτ get '/app/faq', to: redirect(subdomain: "c", path: "/faqs?type=app"), as: :r_app_faq get '/cardy/faq', to: redirect(subdomain: "c", path: "/faqs?type=cardy"), as: :r_cardy_faq get '/app/faq/*id', to: redirect(subdomain: "c", path: "/faqs/%{id}"), as: :r_app_faq_show get '/cardy/faq/*id', to: redirect(subdomain: "c", path: "/faqs/%{id}"), as: :r_cardy_faq_show # چళฮ get '/shop_branches/:id/info', to: "pages/shop_branches#info", as: :info_pages_shop_branch get "/shop_branches/*path", to: redirect(subdomain: "c", path: "/shops/%{path}", status: 301) #-------------------------------- # # ڞ௨ # #-------------------------------- # ELBࢮ׆؂ࢹ get "/hello", to: "generic#hello" # ֤αϒυϝΠϯͷϧʔτύε get "/", to: redirect(subdomain: 'user', path: "/users/index"), constraints: {subdomain: 'user'} get "/", to: redirect(subdomain: 'b', path: "/shops"), constraints: {subdomain: 'b'} get "/", to: redirect(subdomain: '', path: "/app"), constraints: {subdomain: 'c'} get "/", to: redirect(subdomain: '', path: "/"), constraints: {subdomain: 's'} get "/", to: redirect(subdomain: '', path: "/"), constraints: {subdomain: 'api'} get "/", to: redirect(subdomain: '', path: "/"), constraints: {subdomain: 'cardy'} # ωΠςΟϒ ϑοΫ༻ namespace :stamps_shop do get :show_account_input end #-------------------------------- # # ϖʔδ # #-------------------------------- constraints SubdomainConstraint::Page do # ళฮ get '/shops/:code', to: "pages/shop_branches#show", as: :pages_shop_branch # ঺հΫʔϙϯ get "/promotions/:code", to: "pages/user_promotions#show", as: :pages_promotion # App get "/dp", to: "pages/app#data", as: :dp get "/ds/:data", to: "pages/app#ds", as: :ds get "/DS/:data", to: "pages/app#ds" get "/dt", to: "pages/app#dt", as: :dt get "/db", to: "pages/app#dt", as: :db get "/launch", to: "pages/app#launch", as: :launch # FAQ get '/faqs', to: "pages/faqs#index", as: :pages_faqs get '/faqs/doc', to: "pages/faqs#doc", as: :pages_faqs_doc get '/faqs/:id', to: "pages/faqs#show", as: :pages_faq # ϙϦγʔ get '/policies/term', to: "pages/policies#term" get '/policies/privacy', to: "pages/policies#privacy" get '/policies/privacy2', to: "pages/policies#privacy2" get '/policies/personal', to: "pages/policies#personal" get '/policies/personal2', to: "pages/policies#personal2" end #-------------------------------- # # γεςϜ # #-------------------------------- constraints SubdomainConstraint::System do get "/app_ios_version", to: "generic#app_info" get "/shop_app_ios_version", to: "generic#app_info" resources :hooks, only: [] do collection do post :ses_bounce post :cloud_watch get :wanta end end end #-------------------------------- # # ΧελϚ # #-------------------------------- constraints SubdomainConstraint::User do # چΤϯυϙΠϯτ get "/oauth/token", to: "app/user/users#oauth_token" post "/oauth/token", to: "app/user/users#oauth_token", as: :users_oauth_token get "/users/welcome", to: 'app/user/users#welcome' get "/users/fbcallback", to: 'app/user/users#fbcallback' get "/user_messages/:id", to: redirect{ |params, request| "/app/user/user_messages/#{params[:id]}?#{request.query_string}" } get "/app_ios_version", to: redirect(subdomain: "s", path: "/app_ios_version") # چن໿ϦϯΫ get "/app/user/users/term", to: redirect(subdomain: "user", path: "/policies/term") get "/app/user/users/privacy", to: redirect(subdomain: "user", path: "/policies/privacy") # Deviseؔ࿈ get '/users/index', to: 'app/user/users#index', as: :user_root devise_for :users, :controllers => { :registrations=>"users/registrations", :sessions=>"users/sessions", :passwords=>"users/passwords", :confirmations=>"users/confirmations", :omniauth_callbacks=>"users/omniauth_callbacks" } # ΞϓϦWebView namespace :app do namespace :user do resources :home, only: [:index, :show] resources :topics, only: [:show] resources :shop_gifts, only: [:index, :show] resources :shop_catalogs, only: [:show] resources :shop_branches, only: [:index, :show] resources :shop_barcodes, only: [] do member do post :share end end resources :connector, only: [:show, :update] resources :events, only: [] do collection do get '/:code/get_stamp', param: :code, action: 'get_stamp', as: 'get_stamp' get '/:code/stamp_url', param: :code, action: 'stamp_url', as: 'stamp_url' get '/:code/stamp_img', param: :code, action: 'stamp_img', as: 'stamp_img' end member do get :live_stamp_url end end resources :users, only: [] do collection do get :welcome get :fbcallback get :account put :account, action: :account_update get :remove delete :destroy post :share get :contact end end resources :user_cards, only: [:index, :show] do collection do get :load end member do get :content get :history get :term post :permit_push get :user_promotion end end resources :user_coupons, only: [:show] do collection do get :history end member do get :jancode end end resources :user_messages, only: [:index, :show] resource :user_profiles, only: [:update] resources :shop_campaigns, only: [] do resources :user_campaigns, shallow: true do collection do get :thanks end end end resources :user_lottos, only: [:index, :show, :new, :create] end end namespace :api do namespace :app do namespace :v1 do resource :users, only: [:show, :create, :update] do collection do post :login post :refresh_token post :reset_password end end resource :user_devices, only: [:create] resources :user_checkins, only: [:create] resources :user_cards, only: [:index] resources :user_coupons, only: [:index, :show] do member do post :consume end end resources :user_messages, only: [:index] do collection do get :unread end end resources :shop_branches, only: [:index] resources :shop_gifts, only: [:index] do member do post :consume end end end end end end #-------------------------------- # # ΫϥΠΞϯτ # #-------------------------------- constraints SubdomainConstraint::Biz do # Deviseؔ࿈ get '/shops', to: 'shops/root#dashboard', as: :shop_root get '/operation', to: 'operation/root#index', as: :staff_root devise_for :staffs, controllers: { :registrations=>"staffs/registrations", :sessions=>"staffs/sessions", :passwords=>"staffs/passwords", } devise_for :agents, path: 'agency', controllers: { :sessions=>'agency/sessions', :passwords=>'agency/passwords', } # ళฮApp namespace :operation do get '/', to: 'root#index' get '/menu', to: 'root#menu' get '/checkins', to: 'root#checkins' get '/summary', to: 'root#summary' get '/simple_logs', to: 'root#simple_logs' get '/user', to: 'root#user' get '/qrcode', to: 'root#qrcode' resources :shop_barcodes, only: [:index, :show] do member do get :data patch :switch end end resources :users, only: [:show] resources :user_checkins, only: [:index] resources :analyses, only: [:index] end # Agent؅ཧը໘ namespace :agency do root to: "dashboard#index" get "/support_request", to: "dashboard#support_request" resources :shops, only: [:index, :show, :update, :destroy], shallow: true do member do get :proxy_login post :proxy_login get :qrcode end end namespace :admin do resources :agent_groups, shallow: true do resources :agents, except: [:index, :show] end resources :users, only: [:index, :destroy] do collection do post :search post :proxy_login get :lock get :unlock end end resources :connector_logs, only: [:index] do collection do post :search end end resources :shop_messages, only: [:index] namespace :analysis do resources :shops, only: [:index] resources :users, only: [:index] do collection do get :cohort get :data end end end resources :contents resources :topics resources :faq, except: [:show] resources :events do collection do get :reset_cache end end resources :user_logs, only: [:index] do collection do get :search post :search end end resources :audit_logs, only: [:index] do collection do get :search post :search end end end end # ؅ཧը໘ namespace :shops do # Root get :dashboard, to: "root#dashboard" get :support, to: "root#support" # ΞΧ΢ϯτ؅ཧ resources :staffs, only: [:edit, :update, :destroy] do collection do get :index end end resources :accounts, only: [:new, :create] do collection do get :edit post :edit, to: "accounts#update" end end # ళฮઃఆ resources :shop_branches do collection do get :get_data_from_tel end member do get :preview post :draft post :waiting_for_approval post :approve post :publish end end # Χʔυઃఆ resources :shop_cards, shallow: true do collection do get '/:shop_card_id_shop_branch_id/pop', action: 'pop', as: 'pop' get '/:shop_card_id_shop_branch_id/:start_y/:start_m/:start_d/:end_y/:end_m/:end_d/report', action: 'report', as: 'report' get '/:shop_card_id_shop_branch_id/:start_y/:start_m/:start_d/:end_y/:end_m/:end_d/push_report', action: 'push_report', as: 'push_report' get :bulk_new post :bulk_create end member do delete :reset get :bulk_edit patch :bulk_update get :shop_barcodes get :shop_promotions end resources :shop_barcodes, shallow: true do member do patch :suspend patch :restore get :qrcode get :qrcode_pr get :copy end end # ϓογϡ௨஌ resources :shop_messages, except: [:new, :create, :edit, :update], shallow: true do member do post :re_notification get :bulk_edit patch :bulk_update patch :update_label get :copy end collection do get :bulk_new post :bulk_push patch :bulk_push post :preview patch :preview end end # ঺հΫʔϙϯ resource :shop_promotions, only: [:new, :create, :edit, :update, :destroy], shallow: true end # ໊લ෇ QRίʔυ get "/shop_barcodes/:id/:name", to: "shop_barcodes#qrcode", as: :name_shop_barcode # ঺հΫʔϙϯઃఆ resources :shop_promotions, only: [:index] # ελϯϓ෇༩ resources :shop_barcodes, only: [:index] resources :shop_barcode_groups # ϓογϡ௨஌ resources :shop_messages, only: [:index] # Ϋʔϙϯ resources :shop_gifts do member do get :preview post :draft post :waiting_for_approval post :approve post :publish end end # ECαΠτ࿈ܞ resources :connectors, only: [:index, :show] do collection do get :cancel post :cancel end end # ܾࡁ resources :payments, only: [:index, :create] do collection do get :confirm get :apply get :done end end # Χλϩά resources :shop_catalogs, shallow: true do member do get :show_content get :banners get :preview post :draft post :waiting_for_approval post :approve post :publish post :sort end resources :shop_catalog_items, only: [:new, :edit, :create, :update, :destroy] end # Ξϯέʔτ resources :shop_campaigns, shallow: true do resources :user_campaigns, only: [:destroy], shallow: true member do get :copy end end # ෼ੳ namespace :analysis do resources :reports, only: [:index] do collection do post :index post :checkins end end resources :summaries, only: [:index] do collection do post :index post :users_running_total post :user_profiles post :reports post :checkin_each_wday_and_hour post :daily_checkins post :user_checkins get :user_checkins end end resources :visits, only: [:index] do collection do post :index post :sent_messages post :sent_auto_messages post :used_coupons get :sent_messages get :sent_auto_messages
  21. After 1 class ActionDispatch::Routing::Mapper 2 def draw(routes_name) 3 instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb"))) 4

    end 5 end 6 7 Rails.application.routes.draw do 8 draw :gem 9 draw :common 10 draw :page 11 draw :system 12 draw :user 13 draw :biz 14 draw :api 15 end
  22. ։ൃ؀ڥͰͷมߋݕ஌ 1 class RoutesReloader 2 def initialize(app) 3 @app =

    app 4 @routes_reloader = ActiveSupport::FileUpdateChecker.new(Dir.glob("config/ routes/*.rb")) do 5 Rails.application.reload_routes! 6 end 7 end 8 9 def call(env) 10 @routes_reloader.execute_if_updated 11 @app.call(env) 12 end 13 end 14 15 Rails.application.config.middleware.use RoutesReloader if Rails.env.development?
  23. None
  24. routes.rb ·ͩ΍Γ·͢ > େ૟আ.perform

  25. ͢΂ͯͷαϒυϝΠϯ͔Β ͢΂ͯͷϦιʔεʹ ΞΫηεՄೳͳఆٛ...

  26. Before get "/hoges/:id:", to: "pages/hoges#show" get "/fugas/:id:", to: "pages/hoges#show" ɹɹɾ

    ɹɹɾ ɹɹɾ namespace :name do resources :hoges resources :fugas ɹɹɾ ɹɹɾ ɹɹɾ end
  27. ҙਤ͠ͳ͍ΞΫηε https://a.stamp.sc/hoges https://b.stamp.sc/hoges https://c.stamp.sc/hoges

  28. ELBͷϩάΛͻͨ͢Βgrep

  29. After case.1 ௚઀ఆٛ 1 constraints "a" do 2 get "/hoges/:id:",

    to: "pages/hoges#show" 3 end
  30. After case.2 ModuleԽ # ڞ௨ 1 module SubdomainConstraint 2 module

    Base 3 extend self 4 5 def matches?(request) 6 self::NAME_LIST.include?(request.subdomain) 7 end 8 end 9 end # υϝΠϯผ 1 module SubdomainConstraint 2 module Sugoi 3 extend SubdomainConstraint::Base 4 5 NAME_LIST = ["a", "b", "c"] 6 end 7 end 1 constraints SubdomainConstraint::Sugoi do 2 # ͍͢͝ϧʔςΟϯάఆٛ 3 end
  31. Ͳ͕͍͍ͬͪͷʁ • ௚઀ఆٛύλʔϯ • ModuleԽύλʔϯ • # subdomain͕ߟྀ͞ΕΔ redirect_to hoge_path

    # subdomainΛ໌ࣔతʹࢦఆ͠ͳ͍ͱ404ΤϥʔͷͳΔ͜ͱ΋ redirect_to hoge_url(subdomain: "a")
  32. ࢖ΘΕͳ͍ػೳ > େ૟আ.perform

  33. ελʔτΞοϓ͋Δ͋Δ • PMFͷաఔͰ࢈Έམͱ͞ΕΔ • ࣮૷ͨ͜͠ͱʹҙຯ͸͋ͬͨɻ͔͠͠... • ผػೳͰվળɺେ൒͸ͦͪΒʹઃఆҠߦ

  34. ૴Γ͍ͨ...

  35. ׬શʹ࢖ΘΕ͍ͯͳ͍ ɾ ɾ ɾ Θ͚Ͱ͸ͳ͍

  36. SELECT COUNT(*) FROM UNUSED_FUNC_LOGS;

  37. ͋ɺҙ֎ͱগͳ͍

  38. ղܾࡦ • ి࿩ • ΧελϚʔαΫηενʔϜͱڠྗͯ͠ઃఆΛ Ҡߦͯ͠΋Β͏ • టष͘΍Δ͔͠ͳ͍

  39. ૴ͬͨ

  40. ίʔυΛফٕ͢ज़ • HTML/CSS/JSɺٙࣅ໊લۭؒͰফ͠΍͘͢ • DB DROPͤͣʹPrefix෇͚༷ͯࢠݟ !!! %html %head =

    stylesheet_link_tag "app" = javascript_include_tag "app" = csrf_meta_tags %body{class: "#{params[:controller].gsub('/','_')} #{params[:action]}" } #container = yield ALTER TABLE hoge RENAME TO unused_hoge;
  41. Spring Cleaning Well done!!!

  42. None
  43. We Are Hiring

  44. Thanks