Статьи

Создать простое приложение для потоковой передачи музыки с Ruby on Rails

Amazon S3 — отличный способ хранения файлов, но изучение того, как интегрировать его в свой веб-сайт, может оказаться сложной задачей. В этой статье вы узнаете, как интегрировать Amazon S3 и Ruby on Rails посредством создания простого приложения для потоковой передачи музыки.


Amazon S3 — это «хранилище для интернета»

Как утверждает сайт Amazon, Amazon S3 — это «хранилище для Интернета». Это не только недорого, но и быстро и надежно. Это отличный способ размещения контента на вашем сайте, включая изображения, видео или почти все, что вы хотите. Amazon S3 не работает точно так же, как хранилище на вашем компьютере, поэтому вот несколько вещей, которые вы должны знать:

  • В Amazon S3 папки называются «корзинами», а файлы — «объектами».
  • Контейнеры верхнего уровня используются для определения URL-адреса для доступа к вашим данным, поэтому вы можете использовать только имена, которые еще не были заняты. Например, если кто-то уже создал ведро верхнего уровня с именем «videos», вы не можете использовать это имя.
  • Рекомендуется иметь одну корзину верхнего уровня с названием вашего веб-сайта и использовать подуровни корзин для разделения файлов на различные разделы, например изображения, видео или музыку.

Прежде чем продолжить этот урок, необходимо выполнить несколько ключевых действий:

  • Интерпретатор Ruby и RubyGems, установленные на вашем компьютере, вместе с гемом Rails
  • Знание (или, по крайней мере, доступ к нему) вашего идентификатора ключа доступа и секретного ключа доступа для Amazon S3
  • Основное понимание Ruby on Rails

Конечным продуктом этого урока является простое приложение для потоковой передачи и загрузки музыки. В этом приложении пользователь сможет сделать следующее:

  • Просмотр списка всей загруженной в данный момент музыки и загрузка музыки самостоятельно
  • Загружайте музыку различными способами, включая потоковую передачу аудио в формате HTML5, загрузку через HTTP или загрузку через файл .torrent

К тому времени, когда это приложение будет завершено, вы изучите все основные темы, которые вам нужно знать об использовании Amazon S3 в вашем приложении Ruby on Rails.


Драгоценный камень aws-s3 позволяет вам взаимодействовать со службой Amazon S3 в вашем приложении.

Первое, что нужно сделать, это установить рубиновый гем aws-s3 . Этот драгоценный камень позволяет вам взаимодействовать со службой Amazon S3 в вашем приложении. Для этого, если вы находитесь в Windows, просто запустите команду:

1
gem install aws-s3

После того, как это установлено, сгенерируйте наше приложение Rails с помощью следующей команды:

1
rails new mp3app

Последний шаг для запуска вашего приложения — перейти в каталог mp3app / public и удалить файл с именем «index.html». После этого ваше приложение готово к взаимодействию с Amazon S3!


Ваш идентификатор ключа доступа и секретный ключ доступа позволяют подключаться к Amazon S3.

Чтобы мы могли взаимодействовать с Amazon S3, нам нужно сообщить нашему приложению, как войти в Amazon S3. Здесь вам пригодятся ваш идентификатор ключа доступа и секретный ключ доступа. Ваш идентификатор ключа доступа и секретный ключ доступа позволяют подключаться к Amazon S3. Но сначала нам нужно сообщить нашему приложению, что мы используем aws-s3 . Мы делаем это в Gemfile :

1
gem ‘aws-s3’, :require => ‘aws/s3’

Чтобы наше приложение могло использовать этот гем, вам нужно будет ввести command bundle install . Теперь, когда он работает, нам нужно сообщить нашему приложению, как войти в Amazon S3. Мы также делаем это в файле config/application.rb в новой строке внутри класса Application:

1
2
3
4
AWS::S3::Base.establish_connection!(
    :access_key_id => ‘Put your Access Key ID here’,
    :secret_access_key => ‘Put your Secret Access Key here’
)

Этот код указывает нашему приложению создать соединение с Amazon S3, как только оно будет запущено (файл application.rb загружается при запуске приложения). И последнее, что нужно добавить в файл приложения — это константа со значением корзины, которую мы будем использовать. Причина для этого заключается в том, что если нам когда-либо понадобится изменить то, какое ведро мы используем, его нужно будет обновить только в этом одном месте. Это должно выглядеть примерно так:

1
BUCKET=’s3tutorialmusic’

Для этого урока я решил назвать bucket s3tutorialmusic , но вы должны заменить его на тот, который у вас есть на вашем аккаунте. В конце ваш файл должен выглядеть примерно так (но с вашей собственной регистрационной информацией):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
require File.expand_path(‘../boot’, __FILE__)
 
require ‘rails/all’
 
Bundler.require(:default, Rails.env) if defined?(Bundler)
 
module Mp3app
  class Application < Rails::Application
    config.encoding = «utf-8»
    config.filter_parameters += [:password]
 
    AWS::S3::Base.establish_connection!(
      :access_key_id => ‘Put your Access Key ID Here’,
      :secret_access_key => ‘Put your Secred Access Key here’
    )
 
    BUCKET = ‘s3tutorialmusic’
 
  end
end

Теперь мы можем наконец начать работать над тем, чтобы приложение действительно отображало что-то в браузере. Для начала давайте сгенерируем контроллер и представления, которые нам понадобятся. Всего мы сгенерируем три действия для нашего контроллера (которые мы будем называть песнями): index, upload и delete .

  • Индекс будет нашей главной страницей.
  • Действие загрузки предназначено для загрузки новой музыки в Amazon S3, поэтому ее не нужно просматривать.
  • Наконец, действие удаления не будет отображаться и будет отвечать за удаление музыки.

В конце концов, единственное представление, которое нам понадобится для этого приложения, — это представление индекса, поскольку оно будет действовать как центральная панель управления для каждого действия, которое вы можете выполнять. Теперь мы скомбинируем все это в один красивый оператор командной строки:

1
rails g controller Songs index upload delete

Как только это закончится, продолжайте и удалите представления, созданные для upload и delete , потому что они не будут использоваться. Давайте перейдем к написанию кода для действия index!


В действии index готовый продукт позволит пользователям загружать новую музыку и удалять существующую музыку. В файле контроллера этого действия не нужно ничего делать для загрузки новой музыки, но нам нужен список текущих песен, чтобы пользователи могли их удалить.

Во-первых, нам нужно получить объект, который ссылается на наше музыкальное ведро (помните, что имя этого ведра хранится в константе BUCKET). Вот как мы это делаем:

1
AWS::S3::Bucket.find(BUCKET)

Чтобы мы могли использовать методы, доступные в aws-s3 , нам нужно сообщить интерпретатору Ruby, что мы хотим искать функции в пространстве имен AWS::S3 , поэтому это является частью вызова метода. Класс Bucket содержит все методы, связанные с манипулированием ведрами. Наконец, метод find принимает один параметр — имя группы и возвращает объект, который ссылается на эту область. Теперь, когда у нас есть корзина, давайте получим все ее объекты, выполнив это:

1
AWS::S3::Bucket.find(BUCKET).objects

Метод objects возвращает хеш с именами всех объектов в этом сегменте. Наконец, нам нужно сохранить результат этого вызова метода в переменной экземпляра, чтобы мы могли использовать его в нашем представлении. В конце концов, вот как будет выглядеть действие index:

1
2
3
def index
    @songs = AWS::S3::Bucket.find(BUCKET).objects
end

Теперь нам нужно сделать так, чтобы пользователь загружал и удалял музыку. Давайте начнем с последующего и создадим неупорядоченный список всех загруженных в данный момент объектов со ссылкой для удаления этого объекта. Мы можем сделать это так:

1
2
3
4
5
<ul>
<% @songs.each do |song|
   <li><%= song.key %> — <%= link_to «Delete», «songs/delete/?song=» + song.key, :confirm => ‘Are you sure you want to delete ‘ + song.key + ‘?’
<% end %>
</ul>
  • Сначала мы создаем неупорядоченный список.
  • Затем мы перебираем все песни в переменной @songs , используя метод each.
  • Для каждой песни мы создаем элемент списка и создаем текст, который будет отображаться для каждого элемента. Первая часть — это ключ к песням, потому что каждая песня является хешем, а ключ к этому хешу — это название песни.
  • Затем мы помещаем ссылку на действие удаления, где песня может быть удалена. Для URL мы используем строку запроса в конце, чтобы сообщить действию удаления, какую песню нужно удалить.
  • Наконец, у нас есть подтверждающее сообщение, чтобы предупредить пользователя, прежде чем он действительно удалит песню.
1
2
3
4
5
6
if (params[:song])
    AWS::S3::S3Object.find(params[:song], BUCKET).delete
    redirect_to root_path
else
    render :text => «No song was found to delete!»
end
  • Сначала мы проверяем, указан ли параметр песни.
  • Если это так, то мы используем метод find, чтобы получить объект, представляющий эту песню.
  • Наконец, мы используем метод delete, чтобы удалить его из Amazon S3.
  • После этого нам нужно перенаправить пользователя на новую страницу, поскольку действие удаления не отображается. Однако, если параметр песни никогда не указывался, мы просто выводим текст «Песня не найдена для удаления!».

Теперь нам нужно позволить пользователю загружать музыку, потому что это было одним из основных элементов функциональности этого приложения. Сначала мы создаем простую форму, которая позволяет пользователю выбрать файл для загрузки. Мы можем сделать это так:

1
2
3
4
5
<h2>Upload a new MP3:</h2>
<%= form_tag upload_path, :method => «post», :multipart => true do %>
    <%= file_field_tag «mp3file» %>
    <%= submit_tag «Upload» %>
<% end %>

Мы создаем форму, которая отправляет действие загрузки, которое фактически выполняет загрузку в Amazon S3. Мы используем post и multipart, потому что мы отправляем файлы. Помимо этого, эта форма очень проста и легка для понимания, так что теперь мы можем перейти к реализации части этого действия для контроллера.


Нам нужно взять отправленный файл и создать для него новый объект S3, который будет выполнен в действии загрузки. Мы можем сделать это с помощью этой строки кода:

1
AWS::S3::S3Object.store(sanitize_filename(params[:mp3file].original_filename), params[:mp3file].read, BUCKET, :access => :public_read)

В этой одной строке кода происходит много всего, поэтому я объясню каждую часть в отдельности.

Как обычно, мы обращаемся к AWS::S3::S3Object для взаимодействия с объектами в Amazon S3.

Мы используем команду store для фактической загрузки файлов в S3. Первый параметр указывает, что вызывать файл. Для этого мы используем параметр original_filename загруженного файла, чтобы имя оставалось неизменным. Что касается метода sanitize_filename , это будет объяснено в следующем параграфе. Второй параметр — это фактические данные файла, которые получаются при вызове метода read в загруженном файле. Третий параметр указывает используемый сегмент, а четвертый определяет, кто может получить доступ к файлу. Поскольку мы хотим, чтобы каждый мог прочитать файл (включая загрузку), мы указываем доступ как :public_read.

Метод sanitize_filename — это метод, который используется многими людьми и плагинами, например attachment_fu , и используется для решения проблемы с Internet Explorer (шокирует, не так ли?). Вместо того, чтобы просто давать нам имя файла при вызове метода original_filename, IE возвращает полный путь к файлу; например, если файл, который мы хотели загрузить, назывался mysong.mp3 , он вместо этого дал бы нам C:\rails\mp3app\mysong.mp3 когда мы вызываем original_filename . Мы можем исправить это, добавив следующий код в конец контроллера:

1
2
3
4
5
6
private
 
def sanitize_filename(file_name)
    just_filename = File.basename(file_name)
    just_filename.sub(/[^\w\.\-]/,’_’)
end

Наш последний шаг в завершении действия загрузки — добавить проверку ошибок и маршруты. Вы делаете проверку ошибок в ruby ​​с помощью оператора begin...rescue...end . Многие вещи могут пойти не так при загрузке файла, поэтому проверка ошибок не даст пользователю увидеть сообщение об ошибке, которое Rails автоматически сгенерирует. Вот модифицированная версия действия загрузки:

1
2
3
4
5
6
7
8
def upload
    begin
        AWS::S3::S3Object.store(sanitize_filename(params[:mp3file].original_filename), params[:mp3file].read, BUCKET, :access => :public_read)
        redirect_to root_path
    rescue
        render :text => «Couldn’t complete the upload»
    end
end

Если возникает ошибка, мы просто отображаем текст, сообщающий об этом пользователю. Даже если пользователь все еще видит сообщение об ошибке, это лучше, чем огромный список кода, который появится в сообщении об ошибке, сгенерированном Rails.


Возможно, вы заметили, что во всем коде, который мы написали до сих пор, было много раз, когда вместо указания контроллера и действия использовалось что-то вроде upload_path . Мы можем сделать это из-за файла с именем rout.rb. Это сообщает нашему приложению, какие URL доступны в нашем приложении. Мы также даем имена определенным путям, чтобы упростить обновление нашего кода. Вот как вы можете назвать пути, которые будет использовать наш Mp3app:

1
2
3
4
match «songs/upload», :as => «upload»
match «songs/delete», :as => «delete»
 
root :to => «songs#index»

Метод match указывает путь, например, songs/upload , и присваивает ему имя upload_path . Это имя указывается с использованием :as => "name" в качестве второго параметра метода match. Наконец, корневой метод указывает, какое действие будет корневым действием, которое действует подобно index.html на статическом веб-сайте на основе HTML.


Теперь мы закончили реализацию функциональности действия загрузки. Вот окончательный код для файла songs_controller.rb на songs_controller.rb момент:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class SongsController < ApplicationController
  def index
    @songs = AWS::S3::Bucket.find(BUCKET).objects
  end
 
  def upload
    begin
      AWS::S3::S3Object.store(sanitize_filename(params[:mp3file].original_filename), params[:mp3file].read, BUCKET, :access => :public_read)
      redirect_to root_path
    rescue
      render :text => «Couldn’t complete the upload»
    end
  end
 
  def delete
    if (params[:song])
      AWS::S3::S3Object.find(params[:song], BUCKET).delete
      redirect_to root_path
    else
      render :text => «No song was found to delete!»
    end
  end
 
  private
 
  def sanitize_filename(file_name)
    just_filename = File.basename(file_name)
    just_filename.sub(/[^\w\.\-]/,’_’)
  end
 
end

А вот как выглядит приложение, если смотреть в браузере.


Пока что наше приложение прошло долгий путь. Теперь пользователь может загружать музыку, просматривать список загруженной в данный момент музыки и удалять любую существующую музыку. Теперь у нас есть последний кусок основной функциональности для реализации. Это позволяет пользователю на самом деле скачать эту музыку. Как указано в начале этого урока, пользователь может сделать это тремя способами:

  • потоковую передачу с HTML5 Audio,
  • скачать его по HTTP, и
  • скачать его с помощью торрент-файла.

Прямо сейчас, список музыки просто отображается с помощью неупорядоченного списка. Однако, поскольку мы собираемся добавить еще три ссылки в конец каждой строки (по одной для каждого метода загрузки), более целесообразно использовать таблицу для организации списка. Давайте изменим представление индекса, чтобы отразить это изменение:

1
2
3
4
5
6
7
8
9
<h2>Download and Delete Existing MP3’s</h2>
<table>
<% @songs.each do |song|
    <tr>
        <td><%= song.key %></td>
        <td><%= link_to «Delete», «songs/delete/?song=» + song.key, :confirm => ‘Are you sure you want to delete ‘ + song.key + ‘?’
    </tr>
<% end %>
</table>
  • Сначала мы обновляем заголовок, чтобы отразить, что мы также можем загружать музыку.
  • Во-вторых, мы изменим неупорядоченный список на таблицу и поместим название песни и ссылку на скачивание в свои собственные <td>.

Теперь мы готовы добавить код, чтобы позволить пользователю загружать музыку. Давайте начнем с загрузки через HTTP, потому что это самый простой для реализации.


Для загрузки через HTTP нам просто нужно добавить новый <td> в нашу таблицу со ссылкой на файл .mp3. Драгоценный камень aws-s3 имеет встроенные методы, которые позволяют нам генерировать URL для файла. Тем не менее, рекомендуется помещать любые «методы помощи», подобные этим, в вспомогательный файл для этого контроллера. Поскольку мы используем эти методы во всем приложении (особенно если вы решите расширить это приложение самостоятельно), вспомогательные методы будут помещены в application_helper.rb file . Вот как вы получаете URL:

1
2
3
def download_url_for(song_key)
    AWS::S3::S3Object.url_for(song_key, BUCKET, :authenticated => false)
end

Этот метод принимает только один параметр, который является именем песни. Чтобы помочь нам запомнить, что имя песни доступно для song.key, мы вызываем параметр song_key . Как обычно, мы получаем доступ к классу AWS::S3::S3Object для взаимодействия с объектами Amazon S3. Метод url_for принимает два параметра, третий является необязательным.

  • Первый — это имя файла, который вы ищете.
  • Второе — это имя области, в которой находится файл.
  • Наконец, третий параметр используется для предоставления нам URL, срок действия которого не истекает. Если мы не укажем :authenticated => false , срок действия всех URL истечет через 5 минут (по умолчанию).
1
<td><%= link_to «Download», download_url_for(song.key) %></td>

Это <td> между названием песни и ссылкой для удаления (но это личное предпочтение, поэтому вы можете иметь ссылки в любом порядке по вашему выбору).


Загрузка файлов из Amazon S3 через Bit Torrent очень похожа на загрузку через HTTP. Фактически, единственное различие между двумя URL-адресами для загрузки состоит в том, что у торрента есть торрент в конце. Поэтому наш вспомогательный метод для генерации торрент-URL просто добавит? Torrent в конец HTTP-URL. Вот как вы это сделаете:

1
2
3
def torrent_url_for(song_key)
    download_url_for(song_key) + «?torrent»
end

Теперь нам просто нужно добавить еще один <td> в нашу таблицу:

1
<td><%= link_to «Torrent», torrent_url_for(song.key) %></td>

Потоковая передача песен через HTML5-аудио немного сложнее, чем просто загрузка песни, поэтому давайте начнем с простой части: для нее <td> . Однако будут некоторые отличия от ссылок, которые мы добавили для HTTP и Bit Torrent.

  • Во-первых, нам нужен способ идентифицировать эту ссылку, чтобы добавить тег <audio> на страницу, поэтому мы дадим ему класс html5.
  • Во-вторых, нам нужен способ узнать источник mp3, который будет использоваться для <source> , поэтому мы просто дадим ему тот же URL-адрес, что и для загрузки по HTTP. Это также послужит запасным вариантом для браузеров с отключенным javascript, поскольку мы будем использовать javascript для добавления <audio> на страницу.

Вот код для генерации ссылки:

1
<td><%= link_to «HTML5 Audio», download_url_for(song.key), :class => «html5» %></td>

Теперь нам нужно поработать над JavaScript, чтобы добавить звуковой тег на страницу при нажатии на эту ссылку. Для этого мы будем использовать технику, схожую с техникой, которую Джеффри Уэй использует в своем уроке «HTML 5 Audio Element» . Первый шаг — добавить несколько вещей в наши файлы просмотра. В нашем файле layout/application.html.erb нам нужно включить последнюю версию jQuery, потому что это библиотека javascript, которую мы будем использовать. Вот код, который нужно добавить прямо перед первой строкой включения javascript:

1
<%= javascript_include_tag «https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js» %>

Затем измените первый параметр для исходного тега include с: по умолчанию на application.js , потому что именно там мы будем хранить наш код JavaScript, а другие файлы JavaScript по умолчанию не нужны. Затем нам нужно добавить раздел в наше представление index.html.erb, чтобы вставить аудио-тег. В верхней части этого представления нам нужно поместить следующий код:

1
2
3
<h2>Listen to a MP3 with HTML5 Audio</h2>
<section id=»audio»>
</section>

Следуя теме HTML5, мы используем тег section вместо div для создания нашего аудио раздела.

Мы получаем ссылку на аудио раздел и кешируем его в переменной, что считается наилучшей практикой. Далее нам нужно добавить обработчик события click к нашим ссылкам с помощью класса html 5. Когда этот обработчик сработает, нам нужно сделать несколько вещей:

  • Во-первых, нам нужно создать новый звуковой тег и присвоить ему некоторые атрибуты, например элементы управления.
  • Затем нам нужно добавить тег исходного кода, чтобы он действительно знал, что играть.
  • Наконец, нам нужно заменить HTML-код в аудио-разделе новым аудио-тегом и вернуть false, чтобы обычное действие ссылки не выполнялось, то есть загрузка песни. Вот как вы можете собрать все это вместе:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
$(document).ready(function() {
    var audioSection = $(‘section#audio’);
    $(‘a.html5’).click(function() {
 
        var audio = $(‘<audio>’, {
             controls : ‘controls’
        });
 
        var url = $(this).attr(‘href’);
        $(‘<source>’).attr(‘src’, url).appendTo(audio);
        audioSection.html(audio);
        return false;
    });
});

Поскольку это руководство посвящено Ruby on Rails, а не JavaScript, я не буду вдаваться в подробности, объясняющие, как работает этот код. Однако код довольно прост, поэтому вам должно быть легко разобраться. Стоит отметить, что это будет работать только в браузерах, которые поддерживают HTML5 и поддерживают mp3 в качестве допустимых источников для аудио-тегов. Для большинства браузеров последняя версия будет поддерживать этот код HTML 5, но более старые браузеры не поддерживают это.


Мы наконец завершили все основные функции для этого приложения. Пользователь может загружать, скачивать и удалять mp3-файлы различными способами, включая HTML5 Audio, HTTP Downloads и Bit Torrent. Вот как должно выглядеть представление индекса в этой точке:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<h2>Listen to a MP3 with HTML5 Audio</h2>
<section id=»audio»>
</section>
<h2>Upload a new MP3</h2>
<%= form_tag upload_path, :method => «post», :multipart => true do %>
    <%= file_field_tag «mp3file» %>
    <%= submit_tag «Upload» %>
<% end %>
<h2>Download and Delete Existing MP3’s</h2>
<table>
<% @songs.each do |song|
    <tr>
        <td><%= song.key %></td>
        <td><%= link_to «HTML5 Audio», download_url_for(song.key), :class => «html5» %></td>
        <td><%= link_to «Download», download_url_for(song.key) %></td>
        <td><%= link_to «Torrent», torrent_url_for(song.key) %></td>
        <td><%= link_to «Delete», «songs/delete/?song=» + song.key, :confirm => ‘Are you sure you want to delete ‘ + song.key + ‘?’
    </tr>
<% end %>
</table>

Если вы еще этого не сделали, попробуйте запустить этот код и попробовать его сами. Вы можете сделать это, выполнив команду: rails s . Несмотря на то, что мы завершили основную функциональность для этого приложения, есть еще вещи, которые необходимо сделать, такие как стилизация страницы. Давайте сделаем это сейчас.


Первое, что нужно сделать, это обернуть страницу в контейнер, чтобы мы могли центрировать ее. Все, что нам нужно сделать, это поместить div с id контейнера вокруг оператора yield в файле макета, чтобы он выглядел примерно так:

1
2
3
<div id=»container»>
    <%= yield %>
</div>

Далее, мы будем использовать стили от Ryan Bates gem, nifty_generators , чтобы придать нашему приложению некоторые базовые стили. Вот CSS, который мы будем использовать из этого драгоценного камня:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
#container {
  width: 75%;
  margin: 0 auto;
  background-color: #FFF;
  padding: 20px 40px;
  border: solid 1px black;
  margin-top: 20px;
}
body {
  background-color: #4B7399;
  font-family: Verdana, Helvetica, Arial;
  font-size: 14px;
}
.clear {
  clear: both;
  height: 0;
  overflow: hidden;
}

Теперь мы будем работать с индексом. Первое, что нам нужно сделать, это разделить страницу на три раздела. Эти разделы будут заголовком, основным разделом и боковой панелью. В верхней части страницы давайте добавим простой заголовок:

1
2
3
<header>
  <h1>My First Music Streaming Application</h1>
</header>

Далее, давайте разделим страницу на основной регион и область боковой панели. Наш основной регион будет состоять из списка песен, а боковая панель будет содержать аудио HTML5 и форму загрузки. Вот как мы будем изменять код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<div class=»clear»></div>
<section id=»sidebar»>
    <h2>HTML5 Audio</h2>
    <section id=»audio»>
        No song is currently playing.
    </section>
 
    <h2>Upload a Song</h2>
    <%= form_tag upload_path, :method => «post», :multipart => true do %>
        <%= file_field_tag «mp3file» %><br />
        <%= submit_tag «Upload» %>
    <% end %>
</section>
<section id=»main»>
    <h2>Download/Delete Songs</h2>
    <table>
    <% @songs.each do |song|
        <tr>
            <td><%= song.key %></td>
            <td><%= link_to «HTML5 Audio», download_url_for(song.key), :class => «html5» %></td>
            <td><%= link_to «Download», download_url_for(song.key) %></td>
            <td><%= link_to «Torrent», torrent_url_for(song.key) %></td>
            <td><%= link_to «Delete», «songs/delete/?song=» + song.key, :confirm => ‘Are you sure you want to delete ‘ + song.key + ‘?’
        </tr>
    <% end %>
    </table>
</section>
<div class=»clear»></div>

Поскольку мы будем использовать плавающие элементы для оформления этой страницы, нам нужно очистить плавающие элементы до и после, чтобы убедиться, что макет не испорчен. Теперь давайте добавим CSS, чтобы настроить расположение этих разделов:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
#sidebar {
    width: 30%;
    float: left;
}
#main {
    width: 70%;
    float: left;
}
a, a:visited {
    color: #00f;
    text-decoration: none;
}
a:hover {
    text-decoration: underline;
}
td {
    padding: 5px;
}

Боковая панель будет составлять 30% страницы, а основной раздел — 70% страницы. Кроме того, есть CSS для удаления подчеркивания из ссылок, если на него не наведена мышь, а также к тегам <td> добавлен отступ, чтобы он не выглядел так тесно. В конце концов, это действительно единственный CSS, который нам нужен, чтобы дать странице базовый макет. Не стесняйтесь добавлять столько стилей в это приложение, сколько захотите сами, потому что, безусловно, есть способы сделать это приложение более привлекательным.


Надеюсь, у вас теперь есть хорошее понимание того, как взаимодействовать с Amazon S3 из вашего приложения Ruby on Rails. С aws-s3 сделать это очень легко, поэтому добавление его в существующее приложение займет очень мало времени. Не стесняйтесь изменять это приложение любым удобным для вас способом, чтобы увидеть, можете ли вы его улучшить. Не забудьте добавить свою собственную регистрационную информацию Amazon S3 и постоянную корзины в файл application.rb , иначе приложение не запустится!

Для тех из вас, кто является экспертом по Ruby on Rails, я уверен, что вы сможете найти способ еще больше оптимизировать это приложение. Кроме того, было бы замечательно поделиться любой оптимизацией, которую вы делаете в разделе комментариев, чтобы читатели могли получить еще больше от этого урока.