Let's say you have an Article model with a field (string) called embed :
YouTube examples to handle:
https://www.youtube.com/watch?v=u75Zsl1ECPQ&list=PLu9lbDbw-S8zyBwu9_aA2nE-3QocgyzRE&index=4
https://www.youtube.com/watch?v=u75Zsl1ECPQ
https://youtu.be/u75Zsl1ECPQ
https://youtu.be/u75Zsl1ECPQ?t=12
etc..
In the model (note.. I'm not applying width and height in the iframe output, because I'll handle it globally in a stylesheet. Also, you can remove that regex and uncomment self.embed.include? .. to achieve the same validation):
def iframe
if self.embed.present?
### YouTube
## Browser link --- use array to handle most playlist links, etc
if self.embed =~ /^(https?:\/\/)?(www\.)?youtube.com\/watch\?v=/ # self.embed.include? 'https://www.youtube.com/watch?v='
"<iframe src='https://www.youtube.com/embed/#{self.embed[32..42]}' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>"
## YouTube share link --- using array, because .split('https://youtu.be/').last wouldn't handle start at option ()?t=12)
elsif self.embed =~ /^(https?:\/\/)?(www\.)?youtu.be\// # self.embed.include? 'https://youtu.be/'
"<iframe src='https://www.youtube.com/embed/#{self.embed[17..27]}' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>"
### Validate + Generate iframe for whatever other embeds you want to allow (Google Maps, Vimeo, etc)
# elsif
else
self.embed = nil
end
end
end
In the articles#show view (note.. bootstrap classes for handling responsiveness):
<% if @article.embed.present? # no markup if nil %>
<div class="embed-responsive embed-responsive-16by9">
<%= @article.iframe.html_safe %>
</div><!-- .embed-responsive -->
<% end %>
If you want to grab the thumbnail for the embed, this method works the same way:
def thumb
if self.embed.present?
### YouTube
## Each YouTube video has 4 generated images [ /0 .. /3 ]
if self.embed =~ /^(https?:\/\/)?(www\.)?youtube.com\/watch\?v=/
"<img alt='Media' class='card-img-top' src='http://img.youtube.com/vi/#{self.embed[32..42]}/0.jpg' />"
elsif self.embed =~ /^(https?:\/\/)?(www\.)?youtu.be\//
"<img alt='Media' class='card-img-top' src='http://img.youtube.com/vi/#{self.embed[17..27]}/0.jpg' />"
else
self.embed = nil
end
end
end
So, in the articles#index view, you could call on the thumb method:
<% if article.embed.present? %>
<%= link_to article.thumb.html_safe, article_path(article) %>
<% end # consider else.. fallback image ..end %>
Working Example:
https://rails-react-bootstrap.herokuapp.com/articles/45