Rails Diary

プログラミングの学習記録です。

YouTubeやTwitterの埋め込み

フォームに入力されたURLを埋め込みに使いたい

youtube用埋め込みパーシャルのcontent_tagのsrc属性に、フォームから入力されたURLを入れ込む方法を取ろうとするも、ブラウザのyoutube埋め込み箇所には「www.youtube.com で接続が拒否されました。」という表示が出てしまい上手く行かなかった。

/ 変更前
.embed-youtube
  = content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/#{embed.identifier}", \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true

/ 変更後
.embed-youtube
  = content_tag 'iframe', nil, width: width, height: height, src: embed.identifier, \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true

埋め込むURLとブラウザで直接見るURLの違い

YouTube動画埋め込み時に「www.youtube.com で接続が拒否されました。」が表示された際に確認すること | アナライズギア開発ブログ

# 「共有」→「コピー」で取得できるURL
https://youtu.be/IwFO-FNnvrM

# 「共有」→「埋め込む」で取得
https://www.youtube.com/embed/IwFO-FNnvrM

埋め込んで使うタイプのURLにはホスト名とドメインディレクトリ名が加わっていた。src属性にブラウザで直接見るためのURLを入れ込んでも上手く表示できなかったのはこのため。

では、どうしたら良いのか

入力されたURLから末尾のパスのみを取得する

【Ruby】URL文字列から、相対パスを取得する手順 - スリ飯屋MaLankaのフリーエンジニアな日々

やり方は↑のサイトを参考にしました。

※ この項目を書いている時点で相対パスのことをURL末尾のパスと思っていたため、以降の内容にも正しくない表記があるかもしれません。念のため

相対パスとは、現在いるファイルを基準にして説明した対象ファイルの位置のことを指します。(ex: 私の右隣にAさんがいるので、私から見てAさんは私の右隣にいる。私は1階にいて兄は2階にいる。この時、私から見て兄は2階に位置している。)

コンソールで試してみる

※ 課題で元から作られていたアプリを使用しています。

[6] pry(main)> embed = Embed.first
  Embed Load (0.1ms)  SELECT  "embeds".* FROM "embeds" ORDER BY "embeds"."id" ASC LIMIT ?  [["LIMIT", 1]]
   (0.1ms)  select sql from (select * from sqlite_master where type='table' union select * from sqlite_temp_master where type='table') where tbl_name = 'embeds'
=> #<Embed:0x00000001330a7ee8
 id: 1,
 embed_type: "youtube",
 identifier: nil,
 created_at: Mon, 25 Apr 2022 19:27:35 JST +09:00,
 updated_at: Mon, 25 Apr 2022 19:27:35 JST +09:00>
[7] pry(main)> embed.identifier
=> nil
[8] pry(main)> embed.identifier = 'https://youtu.be/IwFO-FNnvrM'
=> "https://youtu.be/IwFO-FNnvrM"
[9] pry(main)> URI.parse(embed.identifier).path
=> "/IwFO-FNnvrM"
[10] pry(main)> URI.parse(embed.identifier).path.delete('/')
=> "IwFO-FNnvrM"
# これでURLの末尾のパスのみ取得できる
URI.parse(URL文字列).path

# /(スラッシュ)はいらないの削除して相対パスを取得する
URI(URL文字列).path.delete('/')

これらを踏まえて

  1. モデルに相対パスを取得するギミックを作成
  2. ビューの埋め込み箇所、content_tagのsrc属性に任意の相対パスを入れ込む
def get_relative_path
   URI.parse(self.identifier).path.delete('/')
end
  • どこのモデルにギミックを記載すべきか分からないので、embed.rbに書いておいた
  • 何通りか試したものの、全部上手く行かずに下記の感じにおさまった(良し悪しはさておき)
【追記】

メソッド名のgetは不適切とチェックが入ったため削除
def get
relative_path

冗長なselfとlintチェックで警告されたため削除
URI.parse(self.identifier).path.delete('/')

↓付随して下記の呼び出し元のビューファイルの表記も修正

.embed-youtube
  = content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/#{embed.relative_path}", \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
  • ビュー側でembedに対し、作成したギミックを呼び出し

URLの相対パスを取得するロジック(別解)

def split_id_from_youtube_url
  identifier.split('/').last if youtube?
end
  • もしYouTubeならスラッシュの区切り文字で分解し、末尾を取得

ツイッターの埋め込み

同じようなツイッター用埋め込みパーシャルを作って、下記サイトに書いてある通りにしたらできた。

TwitterのAPIを使わずに任意のツイートを埋め込む方法 - Sakura scope

.embed-twitter
  blockquote.twitter-tweet
    a href =  "#{embed.identifier}" 
  script async="" charset="utf-8" src="https://platform.twitter.com/widgets.js"