👌

Rails Youtube 動画投稿・編集

2022/07/06に公開

概要

Youtubeにアップロードされた動画をRailsアプリで投稿したいという方に向けたものです。
Youtubeの動画を投稿した時にYoutubeのURLのなかで最後の11桁の値のみを取り出し、他の変数に取り入れるようにしている記事が多い。
それだと編集する時に、末尾11桁を入力しないとエラーが起こってしまうので、それが起きないような、その実装方法を記載します。

事前準備

実装にあたって、私の開発環境を載せておきます。

環境
ruby 3.0.4
Rails 6.1.7

以下のコマンドを入力して、アプリケーションを作成していきます。

ターミナル
rails new youtube_sample
cd youtube_sample

YouTubeURLの種類

1. パソコンでのYouTube閲覧時のURL

https:// www.youtube.com/watch?v=IJks7TIDfnk

https://www.youtube.com/watch?v=IJks7TIDfnk
Screen Shot 2022-07-06 at 17.50.06.png

2. 共有用URL

https:// youtu.be/IJks7TIDfnk

https://youtu.be/IJks7TIDfnk
Screen Shot 2022-07-06 at 17.51.21.png

3.Webサイトへの埋め込みURL

https:// www.youtube.com/embed/IJks7TIDfnk

YouTubeのvideoIDが不正ですhttps://www.youtube.com/embed/IJks7TIDfnk
Screen Shot 2022-07-06 at 17.52.25.png

どのように実装していくか

この3つのURLには共通して末尾に11桁の数字があります。
(https://www.youtube.com/watch?v= [IJks7TIDfnk])ここの部分になります。
これはYouTube チャンネルで使われる標準のURLです。
URLの末尾の英数字部分に、一意のチャンネルIDのことです。

つまり上の2種類のURLが投稿されたら末尾の11桁を取り出し、HTMLに設置した以下の埋め込みURLの末尾にその数字を反映させれば埋め込み動画になります。

Webサイトへの埋め込みURLの末尾11桁を投稿されたurlの末尾11桁にします。
→ https://www.youtube.com/embed/ <11桁のチャンネルID>

railsのhelperでメソッドを作成して、
・1. のURL(https://www.youtube.com/watch?v=WGiUk8VakxQ)
・2. のURL(https://youtu.be/WGiUk8VakxQ)
どちらでもyoutubeが表示するようにします。

実装

1. モデルを作成します。

ターミナル
rails g model Post body:text youtube_url:string
ターミナル
rails generate migration AddYoutubeUrlToPosts youtube_url:string

これでマイグレーションファイルの作成もできました。

ターミナル
rails db:migrate

をしてマイグレーションファイルをupにしましょう。

2. コントローラーを作成します。

ターミナル
rails g controller posts index new show edit

postsコントローラーの中を記述します。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
  end
  
  def new
    @post = Post.new
  end

  def create
    post = Post.new(post_params)
    if post.save
      redirect_to :action => "index"
    else
      redirect_to :action => "new"
    end
  end

  def show
    @post = Post.find(params[:id])
  end

  def edit
    @post = Post.find(params[:id])
  end

  def update
    post = Post.find(params[:id])
    if post.update(post_params)
      redirect_to :action => "show", :id => post.id
    else
      redirect_to :action => "new"
    end
  end

  def destroy
    post = Post.find(params[:id])
    post.destroy
    redirect_to action: :index
  end

  private
  def post_params
    params.require(:post).permit(:body, :youtube_url)
  end
end

3. ルーティングを作成します。

config/routes.rb
resources :posts
root "posts#index"

4. html記述

app/views/posts/index.html.erb
<% @posts.each do |t| %>
  <% if t.youtube_url.present? %>
    <iframe width="560" height="315" src="https://www.youtube.com/embed/<%= find_youtube_url(t.youtube_url) %>" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
  <% end %>
  <%= link_to "詳細へ", post_path(t.id) %>
  <%= link_to "編集する", edit_post_path(t.id) %>
  <%= button_to "削除する", post_path(t.id), method: :delete %>
<% end %>

下記コードが、Youtube表示のコードとなります。

app/views/posts/index.html.erb
<iframe width="560" height="315" src="https://www.youtube.com/embed/<%= find_youtube_url(t.youtube_url) %>" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

上のコードの中にある

<%= find_youtube_url(t.youtube_url) %>

ここにチャンネルIDを入れることでYoutubeを識別させてこうと思います。
ここはメソッドを利用して識別しているので普段見るような形とは違いますが、後で説明します。
今はこのように書くんだなーと思っておいてください。

続いて、投稿画面と編集画面のviewを作成します。
new.html.erbedit.html.erbに下記コード追記してください

app/views/posts/new.html.erb
<%= form_for @post do |f| %>
  <%= f.label :youtube_url %><br>
  <%= f.text_field :youtube_url, :size => 140 %><br>
  <%= f.label :body %><br>
  <%= f.text_field :body, :size => 140 %> <br>
  <%= f.submit "投稿する" %>
<% end %>

5. helperにメソッドの定義

helperは以下の時に使います。
・view内でちょっとした処理をやりたい時。
・定義しておいたメソッドをviewから呼び出す。

app/helpers/posts_helper.rb
module PostsHelper
  def find_youtube_url(youtube_url)
    if youtube_url.include?("https://youtu.be/")
      youtube_url.strip!.gsub("https://youtu.be/", "")
      # "https://youtu.be/WGiUk8VakxQ" 11桁のyoutubeのURLが出力されるようにする
    else
      youtube_url.strip!.gsub("https://www.youtube.com/watch?v=", "")
      # "https://www.youtube.com/watch?v=WGiUk8VakxQ" 11桁のyoutubeのURLが出力されるようにする
    end
  end
end

組んだメソッドの解説をしていきます。
find_youtube_url(youtube_url)
find_youtube_urlで呼び出すようにしました。
引数には投稿されたyoutube_urlが入るようにしてます。

処理の内容はif文を使って投稿内容が
https://youtu.be/ 
↑で始まっているかどうかで分けています。

https://youtu.be/WGiUk8VakxQ

だったらこちらの処理を

youtube_url.strip!.gsub("https://youtu.be/", "")

それ以外は

youtube_url.strip!.gsub("https://www.youtube.com/watch?v=", "")

を行うようにしています。

gsubとstrip!ってなんだよって思うと思います。
こちらはrubyの関数になります。

文字列.strip!
先頭と末尾の空白文字を取り除いた文字列を元の文字列に書きかえる関数です。

具体例を挙げると

ruby.rb
str = " stringです "

puts str
#  stringです 

str.strip!
puts str
# stringです

このように、1度目の出力結果では、空白を出力されいますが、メソッドを利用した後は空白が消えてstrに代入されているのがわかります。

これを利用することで空白を入れて投稿されてもエラーを起きないようにします。

文字列.gsub
文字列中で pattern にマッチする部分全てを文字列 replace で置き換えた文字列を生成して返す関数です。
具体例を挙げると

ruby.rb
str = "HelloWorld"
puts str.gsub("HelloW", "")
# orld

このようにHelloWの部分を""に置き換えて文字列を生成してくれます。

これを利用して、URLのチャンネルIDの11桁を取得して代入するようにしています。

最後に

著者はフロントエンドエンジニアもしくはバックエンドエンジニアを目指して日々勉強中の大学生です。
間違っている点がありましたらご指摘頂けると助かります。
最後までご覧いただき、ありがとうございました。

Discussion