Эта статья была рецензирована Томом Паркином . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!
Канал RSS — это формат данных, используемый веб-сайтами (в основном, блогами) для доставки контента пользователям. Большинство веб-сайтов, включая SitePoint, публикуют фид в качестве другого средства распространения контента. Фид — это поток, в котором обновленный контент публикуется в одном из стандартизированных форматов и может использоваться читателями, например, RSS-клиентами.
Использование RSS-канала позволяет вам следить за многими из ваших любимых веб-сайтов и собирать обновленную информацию в одном месте. Существуют социальные сети и электронные рассылки, которые служат этой цели, но гибкость — это то, что отличает каналы. Существует множество программ чтения каналов, которые позволяют вам вводить все URL-адреса каналов, по которым вы хотите подписаться, и читать их в одном месте. Сегодня мы собираемся создать один такой читатель, чтобы доставить вам удовольствие от чтения. Мы также будем кэшировать содержимое для чтения в автономном режиме.
Давайте начнем.
Начальная загрузка приложения
Мы собираемся построить приложение в Rails 4. Хотя оно может работать со старыми версиями, рекомендуется не отставать от последней версии, чтобы избежать проблем с зависимостями. Давайте создадим наше приложение Rails, выполнив следующую команду:
rails new feedreader -d postgresql
Примечание. Предполагается, что PostgreSQL работает на локальном хосте. Если нет, не стесняйтесь опускать флаг -d
Когда генераторы Rails будут готовы, cd
rake db:create
Давайте также добавим гемные зависимости, которые мы будем использовать в этом приложении. Поскольку это довольно минимальное приложение, нам понадобится всего два гема , feedjira для обработки каналов и twitter-bootstrap-rails для небольшого стилевого оформления. Часть начальной загрузки полностью необязательна, и вы можете игнорировать ее, если хотите использовать свой собственный дизайн.
Добавьте следующие драгоценные камни в Gemfile:
gem 'feedjira'
gem 'twitter-bootstrap-rails'
и запустите bundle install
После завершения установки запустите генератор начальной загрузки:
rails generate bootstrap:install static
Это добавит необходимые файлы начальной загрузки и добавит требуемые require
На этом наша начальная загрузка завершена. Если вы используете контроль версий, что рекомендуется, сейчас самое время для фиксации изменений.
Создание моделей
Пришло время создавать модели для нашего приложения. Структура проста, так как у нас есть только две модели: Feed
Entry
Feed
Entry
Это будет схема для нашего приложения:
Давайте сначала создадим модель Feed. Это достаточно просто, чтобы просто помост. Выполните следующие команды, чтобы восстановить и перенести:
rails g scaffold feed name url description:text
rake db:migrate
Это создает необходимую модель, контроллер и просмотр файлов, связанных с каналами. Нам не нужно вносить никаких изменений ни в один из файлов, просто добавьте root
config / rout.rb :
root 'feeds#index'
Вот и все. Запустите сервер и добавьте ваши любимые каналы. Вероятно, это хорошая идея, чтобы зафиксировать ваши изменения в git:
git add -A
git commit -m "Add Feed scaffold"
Далее, давайте создадим модель Entry
Так как мы собираемся хранить записи с помощью граблей, нет необходимости в полноценных компонентах. Мы можем создать модель Entry напрямую, выполнив следующую команду:
rails g model entry title published:datetime content:text url author feed_id:integer
rake db:migrate
После завершения миграции добавьте отношение к обеим моделям:
## models/feed.rb
class Feed < ActiveRecord::Base
has_many :entries, dependent: :destroy
end
## models/entry.rb
class Entry < ActiveRecord::Base
belongs_to :feed
end
С этим мы полностью уладили модели. Теперь пришло время создать грабли для заполнения модели Entry из добавленных каналов:
Обновление фида
Как я упоминал ранее, у нас будет грабельная задача в качестве точки входа для всех данных в таблице Entries. Эту задачу можно запланировать на выполнение через определенные промежутки времени для синхронизации содержимого канала с нашей базой данных. Начните с создания грабли в lib / tasks с именем sync.rake . После создания файла добавьте в него следующее содержимое:
namespace :sync do
task feeds: [:environment] do
Feed.all.each do |feed|
content = Feedjira::Feed.fetch_and_parse feed.url
content.entries.each do |entry|
local_entry = feed.entries.where(title: entry.title).first_or_initialize
local_entry.update_attributes(content: entry.content, author: entry.author, url: entry.url, published: entry.published)
p "Synced Entry - #{entry.title}"
end
p "Synced Feed - #{feed.name}"
end
end
end
Задача rake проходит по всем каналам, хранящимся в базе данных, и извлекает новейшее содержимое для каждого из них. Начиная с этого, просматривайте новые записи, создавая или обновляя их в базе данных. Мы обновляем каждый раз, чтобы не отставать от любых изменений в исходном контенте.
После того, как вы добавили это, попробуйте запустить задачу rake:
bundle exec rake sync:feeds
Вы можете видеть, что содержимое было добавлено в таблицу Entry. Это легко проверить, войдя в консоль Rails:
$ rails console
> Entry.count
Хорошо, теперь для последнего шага. Давайте создадим контроллер для записей.
Отображение канала
Начнем с создания контроллера для нашей модели Entries. Нам нужно только два действия: index
show
rails g controller entries index show
После выполнения вышеуказанной команды будут созданы файлы контроллера и представления. Перейдите на route.rb, измените следующие строки и добавьте их в ресурсы каналов:
get 'entries/index'
get 'entries/show'
в
resources :feeds do
member do
resources :entries, only: [:index, :show]
end
end
У нас есть вложенные записи под конкретным потоком здесь. Перейдите к контроллеру Entries и добавьте следующее:
# app/controllers/entries_controller.rb
class EntriesController < ApplicationController
before_action :set_feed, only: :index
def index
@entries = @feed.entries.order('published desc')
end
def show
@entry = Entry.find(params[:id])
end
private
def set_feed
@feed = Feed.find(params[:id])
end
end
Мы выбираем соответствующий канал по идентификатору для страницы index
Давайте также внесем необходимые изменения в представления:
# app/views/entries/index.html.erb
<div class="container">
<% @entries.each do |entry| %>
<div class="panel panel-default">
<div class="panel-body">
<%= link_to entry.title, entry %> - <i> published <%= time_ago_in_words(entry.published) %> ago.</i>
</div>
</div>
<% end %>
</div>
# app/views/entries/show.html.erb
<div class="container">
<h3><%= link_to @entry.title, @entry.url %></h3>
<i>published on <%= @entry.published %> by <%= @entry.author %></i>
<p>
<%= @entry.content.html_safe %>
</p>
</div>
Код выше тривиален. Мы отображаем запись, настроенную в соответствии с нашими потребностями. Следует отметить, что мы использовали html_safe
show
Это позволяет нам рендерить HTML в Entry. С этим изменением мы закончили наш крошечный читатель, который просто работает. Сохраните изменения и запустите сервер.
Наше завершенное приложение выглядит примерно так после добавления URL и запуска задачи rake:
Я знаю, что это не самый лучший читатель фидов, но он позволяет вам его создать. У нас есть функциональность, теперь используйте ваше воображение для дизайна.
Вывод
Весь пример кода, используемый в этом уроке, доступен на Github, не стесняйтесь разбирать и тыкать.
Спасибо, что нашли время прочитать этот учебник, и я надеюсь, что он послужил вашим целям До скорого.