52 Поста

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

В прошлых постах я довольно подробно рассмотрел основы Ruby и Rails, но возможно у меня не хватит времени на разбор чуть более продвинутых компонентов. Которые, впрочем, вы можете изучить и самостоятельно, зная основы.

Что такое ORM

ORM сопоставляет объект и реляционную базу данных.

Object-relational mapping — объектно-реляционное сопоставление.

Это сопоставление убирает разрыв между реляционными базами данных, которые спроектированы на основе математической теории множеств, и объектно-ориентированными языками программирования, которые имеют дело с объектами и их поведением.

Также ORM упрощает написание кода для доступа к базе данных.

В Rails, Модель обычно использует какой-то ORM-фреймворк.

Фреймворком по умолчанию является Active Record.

Базы данных

SQLite довольно легкая и простая база данных, но для большинства проектов вам могут понадобиться такие базы данных как PostgreSQL или MongoDB.

Postgres является объектно-реляционной базой данных, она хорошо подходит для хранения разнообразной информации.

MongoDB является NoSQL базой данных, она использует JSON-подобные документы. Она также подходит для хранения больших объемов данных или медиафайлов.

Иногда вам могут встречаться прочие БД, например MySQL.

CRUD

CRUD (create, read, update, delete) — четыре базовые функции, используемые при работе с базами данных и прочими хранилищами информации:

  • Создание
  • Чтение
  • Редактирование
  • Удаление

Пример:

Операция SQL-оператор HTTP-операция
Создание (create) INSERT POST
Чтение (read) SELECT GET
Редактирование (update) UPDATE PUT или PATCH
Удаление (delete) DELETE DELETE

Также CRUD может означать пользовательский интерфейс с такими функциями.

AngelList — это американский сайт для стартапов, людей ищущих работу и инвесторов.

На главной есть несколько примеров известных компаний, которые предлагают работу на этом сайте.

На сайте много стартапов из Кремниевой Долины, США, Европы и других стран. Они ищут разработчиков, инженеров, учёных, менеджеров.

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

Как я искал работу

Так как на сайте много технологических компаний, которым нужны талантливые разработчики, поиск не составлял труда. По запросу «Ruby on Rails, Europe» на сайте около 200 вакансий.

В основном кроме RoR для такой работы нужно владеть: AngularJS (иногда React), HTML5/CSS3, RSpec, навыками работы с базами данных и прочим.

То есть, что неудивительно, Ruby on Rails разработчики чаще всего должны владеть полным стеком.

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

Пока что я проявил заинтересованность к различным компаниям из Амстердама, Берлина, Барселоны, Парижа и т.д.

Многие компании готовы сотрудничать удаленно, некоторые предпочитают пригласить работника в офис.

В этом посте я расскажу о своем опыте поиска работы веб-разработчиком в странах ЕС.

Для начала, я написал резюме в формате PDF. Затем начал искать в Google «ruby on rails jobs germany», «ruby on rails remote jobs» и т.п.

В основном, отправлял на почту резюме с небольшим сопроводительным письмом и ссылкой на демо-проект с исходным кодом.

Первый ответ

По второй заявке со мной связался CTO (и заодно владелец/директор компании), это было агентство из Берлина.

Меня попросили выполнить тестовое задание: небольшое приложение с использованием Ruby on Rails и AngularJS/React (я выбрал Angular). Оно имело небольшой функционал (регистрацию, аутентификацию, загрузку изображений и их просмотр), но при этом покрывало большинство основных навыков.

Также попросили заполнить опросник. На первой странице опросника были общие вопросы, на второй просили оценить свои навыки по пятибалльной шкале (там был большой список, начиная от основных языков программирования и фреймворков, заканчивая стрессоустойчивостью и прочим).

Третья страница была самой интересной: на ней было несколько десятков технических вопросов по Ruby on Rails, а также вопросов для понимания моего мышления в профессиональном плане.

Было интересно, заняло некоторое время на полное заполнение.

В общем, отправил заполненный опросник и готовое тестовое задание обратно.

Первое интервью

CTO понравилось мое выполнение, он пригласил меня на интервью — для начала с HR.

Мне пришлось написать этому коллеге самому, он предложил skype-интервью. Договорились о времени.

В назначенное время он мне позвонил. Разговор длился около 20-30 минут.

Мы обсуждали общие вопросы, такие как зарплата, то как мы будет работать и т.д.

Договорились, что для начала я буду работать удаленно, и если всё пойдет хорошо, они пригласят меня в Берлин.

Если бы им всё понравилось, меня ждало бы второе интервью с CTO/CEO.

Отказ

Некоторое время я ждал ответа, напомнил об этом HR. Я сразу подумал, что если бы они предпочли меня, то связались бы быстрее.

Как я мог ожидать, я получил вежливый отказ:

I´m very sorry for answering that late. After talking to my customer he
decided not to go on with you at the moment. But we hope to cooperate
with you to an other time.

Что дальше

Пока я ожидал ответа, я продолжал рассылать заявки. Опять же, часть из них была отправкой резюме на e-mail, часть заявок оставлялась на сайтах компаний.

Многие вакансии требовали больше опыта работы чем у меня фактически имелось, некоторые из них просто предпочитали местных.

Пара примеров ответов:

Hi Kirill,
Thank you for your application! Unfortunately we’ve reviewed your application and have decided we won’t be moving forward with you for this role you applied. This is mainly because we are at the moment looking developers with a bit more experience.
Thanks again for your in interest in working with us. We’ll be sure to keep you in mind if anything new comes up that’s a good fit.
Best regards,
Tiina / Codemate HR

Ищут чуть более опытного разработчика — ответили как есть.

Вот последний ответ:

Dear Kirill,
Thank you for submitting your application and showing interest in Clark.
After careful examination of your application, we regret to inform you that we cannot take it into further consideration. We receive many great applications and therefore decisions are often based on minor differences. Please be assured therefore, that we do not question your qualifications or you as a person.
We appreciate your time and interest in Clark and wish you the best in your current job search. Please note that this email only counts for this position, if you applied for several openings, you will get separate feedback for all of your applications.
Kind regards,
Your Clark Recruiting Team

В целом, это довольно стандартные ответы для вежливого отказа. Им приходит множество заявок, только небольшая часть идет дальше (тестовое задание, интервью), и всего лишь одного или нескольких нанимают.

Поиск продолжается

Продолжаю отправлять заявки в европейские страны.

Европа не маленькая:

Карта Европы и ЕС

На карте отмечены страны европейского союза.

Кроме прямого поиска, я начал искать работу на AngelList. Примерно так выглядит мой профиль:

Kirill Topolyan, AngelList

Работает AngelList довольно интересно. К примеру, я вбиваю в поиск «Ruby on Rails, Germany» или «Ruby on Rails, Europe», и вижу список компаний/вакансий, для которых выбираю «интересно» или «пропустить».

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

Немного напоминает сервисы знакомств, кстати.

Что удивило

Показалось слегка интересным, что в вакансиях часто указано «m/f». К примеру, «Ruby on Rails Developer, m/f», «Full-Stack Web Developer, m/f».

Наверное, европейцы и американцы хотят таким образом показать свою непредвзятость по половому признаку.

Иногда встречаются вопросы по поводу пола и расы, видимо чтобы компании могли соответствовать квотам по найму меньшинств.

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

В этом посте я расскажу о развертывании приложения на Heroku.

Прежде всего, что такое Heroku? Heroku — это PaaS. Платформа как услуга (Platform as a Service). Некоторые люди называют это облаком.

Они позволяют развертывать приложения на своей платформе.

Как и у любого хорошего бизнеса, их тарифы меняются время от времени, но они всегда предоставляли бесплатный аккаунт.

Так что, вы можете зарегистрироваться бесплатно на heroku.com.

Heroku CLI

Heroku имеет CLI — интерфейс командной строки (command line interface). Он позволяет вам управлять вашими приложениями на Heroku.

Раньше он назывался Heroku Toolbelt.

Установка довольно простая и описана на их сайте: https://devcenter.heroku.com/articles/heroku-cli.

Последние шаги

Heroku использует Postgres и рекоммендует gem rails_12factor.

Так что, нужно перенести gem sqlite в режим разработки, а нужные gem’ы добавить в режим production.

После добавления gem’ов, запустите bundle и сделайте коммит в свой локальный репозиторий.

Пишем в терминале heroku login, вводим e-mail/пароль.

После успешной авторизации, выполняем heroku create name, где name — имя приложения. Если вы не вводите его, Heroku выберет свободное имя для вас.

Другая вещь, которую Heroku делает при выполнении этой команды, это создание удаленного git-репозитория, в который вы можете сделать push.

Можете это проверить с помощью git remote -v или git branch -av.

Это практически всё. Далее вы делаете git push heroku master и наблюдаете за результатом.

Не забудьте убедиться, что корневая папка вашего репозитория содержит папки и файлы Rails-приложения (такие как app и т.д.). Это то как Heroku узнает какое это приложение.

Можно выполнить heroku open, это откроет ссылку в браузере.

Теперь ваше приложение не на локалхосте, ваше приложение работает в реальном вебе.

В итоге

Зарегистрируйтесь на Heroku и скачайте их CLI.

Не забудьте сделать изменения в Gemfile.

В этом небольшом посте мы рассмотрим интеграцию Rails с HTTParty.

Для начала добавляем HTTParty в Gemfile.

Затем выполняем команду bundle install или просто bundle.


(…)

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

Gem’ы загружаются при запуске сервера, поэтому это один из нескольких случаев, когда следует перезапускать его.

В этом посте мы рассмотрим Bundler и управление gem’ами внутри вашего Rails-приложения.

Если вы зайдете на bundler.io, вы увидите, что «Bundler обеспечивает согласованную среду для проектов Ruby, отслеживая и устанавливая точные gem’ы и версии, которые необходимы».

Bundler

Bundler позволяет вам указывать gem’ы (и связанные с ними зависимости) для Rails-приложения внутри файла Gemfile (в его корневой директории).

Это наиболее предпочтительный способ управления зависимостями gem’ов в Rails.

Чтобы использовать его, выполните bundle install или просто bundle после указания нового gem’а в Gemfile.

Если вы изменяете версию gem’а, выполните bundle update.

Кроме того, вы можете сказать Rails (опять же, через Gemfile) загружать определенные gem’ы только в определенных окружениях.

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

Какая версия устанавливается

Если вы не указываете ничего, вы получаете последнюю версию.

Вы также можете указать точную или примерную версию.


gem 'rails', '4.2.6' # точная версия
gem 'sqlite3' # последняя версия
gem 'uglifier', '>= 1.3.0' # версия старше (или равная) 1.3.0

Другой пример:


gem 'thin', ">= 1.1", "< 2.0" # не менее 1.1, но менее 2.0
gem 'thin', "~>= 1.1" # то же, что и в примере выше

Подобное значение может указываться, потому что часто при переходе на новую версию gem’ы (и программное обеспечение вообще) могут менять или удалять определенные API.

Во втором варианте этого примера, bundler отбрасывает последнее число и увеличивает первое, чтобы получить верхний лимит номера версии.

Пример Gemfile

Приложение может даже использовать другую версию Rails, если вы меняете версию в Gemfile и выполняете bundle update.


source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.6'

Кроме того, Bundler создает файл Gemfile.lock, который содержит фактические версии gem’ов с их зависимостями, которые использует ваше приложение.

bundle exec

Скриншот документации:

Допустим, у вас есть три или четыре разные версии, скажем, rake. Может быть не так очевидно, какую из них использовать.

При выполнении bundle exec rake вы будете точно знать, что выполняется версия из Gemfile.

В итоге

Bundler управляет зависимостями gem’ов.

Он загружает gem’ы при запуске приложения.

В этом посте мы рассмотрим gem’ы в Ruby в общем, а также конкретный gem под названием HTTParty.

Итак, RubyGems — это, в целом, менеджер пакетов. Вы можете посмотреть информацию о нём на сайте rubygems.org. Там действительно можно найти сотни и тысячи сторонних gem’ов.

Также, Gem — это менеджер пакетов, который устанавливается вместе с установкой Ruby. Вы можете выполнять такие команды как gem install name.

Если вы хотите узнать, установлен ли gem, вы можете сделать gem list, в этом случае httparty.

Если он не установлен, выполните команду gem install httparty.

Вы также можете увидеть больше деталей о gem’е с помощью команды gem list httparty -d.

Что такое Restful веб-сервисы

Restful веб-сервисы это простые веб-сервисы реализованные с помощью HTTP (и принципов REST), которые:

  • Имеют базовый URI
  • Поддерживают форматы обмена данными такие как JSON и XML (и, возможно, другие)
  • Поддерживают набор HTTP-операций (GET, POST и т.д.)

Вместо того, чтобы думать о вебе в целом как о куче HTML-страниц, подумайте о нём как о том, что больше соответствует MVC-шаблону, который мы обсуждали.

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

Некоторые форматы легче парсить, чем другие. К примеру, HTML не очень подходит для парсинга, но XML и JSON подходят хорошо.

Означает ли это, что вы должны изучить полностью новый формат и писать парсер для него в Ruby?

Нет, потому что это как раз то где на помощь приходит HTTParty.

Gem HTTParty

HTTParty это клиент для Restful веб-сервисов.

Представьте браузер. Ваш браузер является клиентом веб-сайта, и чаще всего вы видите HTML-страницы в нём.

Ваш браузер запрашивает что-то с сервера, сервер возвращает это, и браузер это отображает.

Но, опять же, эти данные трудно парсить. Поэтому, если вы хотите использовать их, к примеру, для коммуникации между двумя сайтами и запрашиваете информацию с другого Rails-приложения, вам больше подойдет формат который легко парсить, а не только легко отображать.

HTTParty обеспечивает автоматический парсинг JSON и XML в ваши хэши (или массивы) Ruby.

Пока формат является валидным JSON или XML, HTTParty легко парсит данные в структуры Ruby, и затем вы можете просто использовать их.

Использование HTTParty

Это, на самом деле, довольно просто. Включаете модуль HTTParty в код и вы готовы!

Вы также можете указать:

  • base_uri для ваших запросов
  • default_params (к примеру, ключ API)
  • format, чтобы указать в каком формате данные

Плагин JSONView

Для браузеров (Chrome, Firefox и возможно других) есть плагин JSONView, который позволяет удобно просматривать файлы JSON.

С этим плагином JSON API будет выглядеть примерно так:

В общем, рекомендую установить.

Пример URL в API

Пример URL в API:

Через ? указываются параметры, второй параметр (как и следующие) указывается через &.

В данном примере мы запрашиваем контент определенного изображения с параметрами высоты и ширины не ниже заданных размеров.

В итоге

HTTParty позволяет чрезвычайно просто интегрировать Restful-сервисы, конвертируя их в хэши Ruby.

Поддерживаются форматы JSON и XML.

В этом посте мы рассмотрим:

  • Что такое хелперы и чем они полезны
  • Зачем использовать Rails-хелпер link_to

Хелперы

Чтобы понять концепцию хелперов, давайте взглянем на переменную текущего времени, которая была определена в нашем контроллере (что хорошо).

Что если мы хотим форматировать то, как выглядит это время?

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

Должен ли он быть в контроллере? Вряд ли, потому что контроллер должен быть независим от формата представления.

Так что, здесь приходят на помощь хелперы.

Каждый раз, когда вы генерируете контроллер, также генерируется (пустой) хелпер.

Давайте добавим в него метод.

Интересно то, что метод внутри хелпера будет доступен для всех view в вашем приложении.

Не забываем указать formatted_time(@time) во view.

И это работает, на странице показывается отформатированное время.

Встроенные в Rails хелперы: link_to

Rails предоставляет много встроенных хелперов.

Один из них, это хелпер link_to.

link_to name, path генерирует гиперссылку, которая отображает имя (name) и ссылается на путь (path).

В вашем HTML вы будете иметь тег <a>.

Путь может быть обычной строкой или маршрутом указанным в файле routes.rb, и оканчиваться на _url (полный путь) или _path (относительный путь).

Это полезно потому, что вы можете указать переменную, и ваша страница изменится автоматически, если изменится эта переменная.

link_to в действии

Добавим пару ссылок в наш view.

Первый параметр это имя.

В первом примере мы ссылаемся на Google и определяем полный URL, во втором — используем внутренний путь, определенный в routes.rb.

Конечно, это будет работать без проблем.

В итоге

Хелперы являются «макросами» для вашего Представления.

При использовании link_to, нет необходимости что-то менять, когда меняется путь.
Поэтому он может быть удобнее простого HTML-тега.

В этом посте мы рассмотрим то, как перенести бизнес-логику из Представления в Контроллер в соответствии с MVC-паттерном.

Также мы поговорим о том, как долго переменные экземпляров контроллера остаются на месте.

Действия (методы) внутри контроллера

Если действие (метод) ничего не делает, мы можем просто убрать его.

Пока определен правильный маршрут и есть правильно названный файл/шаблон представления, действие не обязано присутствовать, и Rails найдет правильный шаблон при помощи конвенции.

Контроллер: новый вид

Так что, мы можем закомментировать (или просто удалить) действия в нашем контроллере, и он всё еще будет работать.

Но, конечно же, есть причина иметь действия внутри контроллера, они не просто для декорации.

Переносим бизнес-логику

Наше приложение работает, но бизнес-логика не должна находиться во View. Представление должно иметь настолько мало Ruby-кода, насколько это возможно.

Давайте перенесем эту бизнес-логику из Представления в Контроллер.

Переменные экземпляров из контроллера доступны внутри view.

Попробуем также добавить счетчик просмотров. Изначально, @times_displayed будет равняться 0, и с каждым просмотром страницы это число должно увеличиваться на 1.

Здесь мы просто используем переменные из контроллера.

Посмотрим что получилось.

В обоих случаях просмотрено 1 раз? Интересно.

Переменные экземпляров в Rails

Дело в том, что, в отличие от других веб-фреймворков (к примеру, Servlets), вы не можете хранить значения в переменных контроллера между запросами.

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

Какие альтернативы? Можно хранить их в HTTP-сессии, либо в базе данных.

В итоге

Старайтесь держать бизнес-логику вне View.

Переменные экземпляров в контроллере доступны для View.

Переменные экземпляров не задерживаются между запросами.

В этом посте мы рассмотрим как работает маршрутизация, что такое Rake и как анализировать ваши маршруты.

Маршруты

В предыдущем посте мы пытались добавить действие «goodbay» в наш контроллер, но это не сработало, потому что не хватало еще одной важной части. Этой частью является маршрутизация.

Перед тем как контроллер может скоординировать куда идет веб-запрос, этот запрос должен быть направлен к контроллеру.

Так как работало действие «hello»?

Маршрут к нему был автоматически сгенерирован, когда мы выполняли rails g controller.

Давайте дополним цикл MVC из одного из прошлых постов.

  1. Отправлен запрос
  2. Маршрутизатор направляет запрос к контроллеру
  3. Контроллер ← → Модель
  4. Контроллер запускает Представление
  5. Представление отображает данные

routes.rb

Все маршруты должны быть указаны (вручную или с помощью генератора) в файле config/routes.rb.

Как этой файл выглядит?

Изначально в нём много комментариев.

Запись get 'greeter/hello' означает, что когда вы отправляете get-запрос, к примеру в браузере, он должен быть интерпретирован как «контроллер greeter, действие hello».

Давайте добавим маршрут для действия goodbay.

Мы можем указать просто get 'greeter/hello' (или 'greeter/goodbay'), или мы можем указать это в стиле get 'greeter/hello' => "greeter#hello", что означает, что этот запрос направляется к «контроллер greeter, действие hello».

В данном примере они не имеют разницы, но если бы вы хотели указать другой адрес слева, вы бы использовали именно второй способ.

Итак, наш маршрут для goodbay работает.

Rake

Rake это язык сборки Ruby. Его имя происходит от «Ruby’s make».

В отличие, к примеру, от Ant в Java, он не написан на XML, он написан только на Ruby.

Rails использует Rake для автоматизации связанных с приложением заданий, к примеру операций с базой данных, тестами и т.д.

Чтобы увидеть список всех rake-заданий для вашего приложения, можно выполнить rake --tasks.

Также можно запросить описание индивидуального задания с помощью rake --describe.

rake routes показывает все ваши указанные маршруты.

В итоге

Маршрут направляет запрос к правильному контроллеру.

rake routes позволяет увидеть какие маршруты на данный момент определены в вашем приложении.