埋め込みメディア(コンテンツ)とは?
サイト内に他のコンテンツ(YouTube,Twitter,Instagramなど)を組み込むこと。
今や、数々のWebサイト内で導入されている!!!!
■現状:
現在、埋め込みタイプとして選択できるのは、YouTubeの一択です。

■期待する機能:
①組み込みタイプに「Twitter」を追加する。
②ブロックヘッダーのアイコンもYoutube/Twitterと適切に切り替わるようする。
③Twitterが選択された場合とYouTubeが選択された場合で処理を分岐。
④ブロック追加画面のアイコンはYoutubeとTwitterの二つが表示されるようにしてください。
⑤Youtube/TwitterどちらもURLでカードが表示されるようする。
⑥twitterのツイートを埋め込みコンテンツとして選択できるようにしてください(タイムラインではありません)。
===========================================================================
■導入手順
①enumの作成

app/models/embed.rb
class Embed < ApplicationRecord
has_one :article_block, as: :blockable, dependent: :destroy
has_one :article, through: :article_block
enum embed_type: { youtube: 0, twitter: 1 } #youtubeとtwitterを追加する。 追加したら、選択欄に2つが選択できるようになる。
validates :identifier, length: { maximum: 200 }
end
app/views/admin/articles/article_blocks/_edit_embed.html.slim
.box-body
= f.input :embed_type, collect: Embed.embed_types_i18n.invert, include_blank: false
= f.input :identifier
#simple_formの中で、Youtubeかtwitterかを選択し、identifierを入力できるようなフォームにします。
②記事ブロック見出しアイコンをTwitterに対応させる/③Twitterが選択された場合とYouTubeが選択された場合で処理を分岐。
下記のように、コンテンツの横にアイコンが出るようにする。


app/decorators/article_block_decorator.rb
module ArticleBlockDecorator
def box_header_iconif sentence?
'<i class="fa fa-edit"></i>'.html_safe
elsif medium?
'<i class="fa fa-image"></i>'.html_safe
elsif embed?
blockable.youtube? ? '<i class="fa fa-youtube-play"></i>'.html_safe : '<i class="fa fa-twitter"></i>'.html_safe # 三項演算子を使いスッキリ書く
# blockable.youtube = ブロック追加でyoutubeを選択するか否か。youtubeを選択した場合は、埋め込みの横に「YouTubeロゴ」を出す。それ以外は「Twitterロゴ」を出す
end
end
end
Rspecで引っかかる記載:
このようにif文の中にif文を作ると、RubocopのLintチェックに引っかかりました。
Metrics/PerceivedComplexity: Perceived complexity for box_header_icon is too high. [8/7]
app/decorators/article_block_decorator.rb
module ArticleBlockDecorator
def box_header_icon
if sentence?
'<i class="fa fa-edit"></i>'.html_safe
elsif medium?
'<i class="fa fa-image"></i>'.html_safe
elsif embed?
if blockable.embed_type == 'youtube' #if文の中にif文を入れると処理が複雑化しすぎるため、処理が遅くなる!!!
'<i class="fa fa-youtube-play"></i>'.html_safe
elsif blockable.embed_type == 'twitter'
'<i class="fa fa-twitter"></i>'.html_safe
end
end
end
end
④ブロック追加画面のアイコンはYoutubeとTwitterの二つが表示されるようにしてください。
記事ブロック挿入画面のアイコンを、YouTubeとTwitterが横並びになるようする。

= link_to admin_article_article_blocks_path(article.uuid), \
class: %w[btn btn-app btn-default js-insert-article-block], \
data: { \
remote: true, \
disable: true, \
method: :post, \
params: { article_block: { level: level, blockable_type: 'embed' } } \
} do
**.d-inline-flex #**インラインのFlexコンテナーでこれで囲うことで表示を横並びにできる!!
**i.fa.fa-youtube-play
i.fa.fa-twitter**
'
| 埋め込み
[checkポイント]
bootstrapで用意されているインラインのFlexコンテナーです。
こちらを使うことで、横並びを実現しています。
ブラウザでは下記のようにレンダリングされています。
<div class="d-inline-flex">
<i class="fa fa-youtube-play"></i>
<i class="fa fa-twitter"></i>
</div>
⑤Youtube/TwitterどちらもURLでカードが表示されるようする。
youtube再生画面の「共有」を押した後に表示される埋め込み用URLというのは、以下の構成になっています。

https://www.youtube.com/embed/11桁のID
[重要ポイント]
各動画は / より後ろの文字列により個別に分類されているので、
上記のURLを取得後、 / より後ろの文字列を取得し、「任意のYouTubeのID」に代入すると任意のYouTubeが表示されるようになります。
ID抽出メソッド作成:
以下のように、/ を区切り文字としてyoutubeのURLを後ろのidのみを抽出するsplitメソッドをEmbedモデル定義しましょう。
app/models/embed.rb
class Embed < ApplicationRecord
has_one :article_block, as: :blockable, dependent: :destroy
has_one :article, through: :article_block
def split_id_from_youtube_url
identifier.split('/').last if youtube? #splitメソッドで「/」を区切り文字としてyoutubeのURLを後ろのidのみを抽出する!!!!
end
enum embed_type: { youtube: 0, twitter: 1 } #youtubeとtwitterを追加する。 追加したら、選択欄に2つが選択できるようになる。
validates :identifier, length: { maximum: 200 }
end
embedに対して、作成したメソッドを実行して下11桁の文字列だけ取り出して表示させましょう。
app/views/shared/_embed_youtube.html.slim
.embed-youtube
= content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/**#{embed.split_id_from_youtube_url}**", \
frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true #{}の中に上でメソッド定義した「split_id_from_youtube_url」を入れる
⑥twitterのツイートを埋め込みコンテンツとして選択できるようにしてください(タイムラインではありません)。
tweet埋め込みツールは公式にて用意されています。
公式ツールからコピーした埋め込み用HTML
<blockquote class="twitter-tweet">
<p lang="en" dir="ltr">Sunsets don't get much better than this one over
<a href="[https://twitter.com/GrandTetonNPS?ref_src=twsrc^tfw](https://twitter.com/GrandTetonNPS?ref_src=twsrc%5Etfw)">@GrandTetonNPS</a>.
<a href="[https://twitter.com/hashtag/nature?src=hash&ref_src=twsrc^tfw](https://twitter.com/hashtag/nature?src=hash&ref_src=twsrc%5Etfw)">#nature</a>
<a href="[https://twitter.com/hashtag/sunset?src=hash&ref_src=twsrc^tfw](https://twitter.com/hashtag/sunset?src=hash&ref_src=twsrc%5Etfw)">#sunset</a>
<a href="[http://t.co/YuKy2rcjyU](http://t.co/YuKy2rcjyU)">[pic.twitter.com/YuKy2rcjyU](http://pic.twitter.com/YuKy2rcjyU)</a>
</p>
<a href="[https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc^tfw](https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc%5Etfw)">May 5, 2014</a>
</blockquote>
<script async src="[https://platform.twitter.com/widgets.js](https://platform.twitter.com/widgets.js)" charset="utf-8"></script>
無駄な部分を省いて、必要な部分だけ残します。
公式ツールからコピーした埋め込み用HTML
<blockquote class="twitter-tweet">
<a href="https://twitter.com/freelife_blog/status/1461534705292132354?ref_src=twsrc%5Etfw"></a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
slim形式に変換して整えます。
app/views/shared/_embed_twitter.html.slim
.embed-twitter
blockquote.twitter-tweet
a href="#{embed.identifier}" # tweetのURL部分に、embedのidentifierを入れる
script async="" charset="utf-8" src="[https://platform.twitter.com/widgets.js](https://platform.twitter.com/widgets.js)"