Декораторы в rails

Продолжая топик о презентерах.

У постов есть статус, в простом варианте true\false, если в шаблоне выводить просто @post.status, то ничего хорошего из этого не выйдет. Хочется например как-то так:

Логичное продолжение – перенос этой логики в helper.

Основным недостатком хелперов является “загрязнение” глобальной области видимости. Кстати, в данном конкретном случае с post, такой вариант возможно и выгоден, если все модели содержат поле статус, и должны выводить подобное сообщение.

Но с декораторами можно перенести логику шаблона в отдельный модуль (инкапсулировать). Rails по умолчанию не создаёт папки decorators, надо это сделать в папке app. А в папке decorators файл post_decorator.rb

Декоратор должен содержать конструктор в который передаётся объект который надо декорировать.
Continue reading “Декораторы в rails”

Презентер в rails

По мотивам Ruby on Rails – Presenters & decorators

Презентер

С прогрессом проекта шаблоны становятся сложнее, там появляется нетривиальная логика. И конечно же контроллеры тоже разрастаются. Существует такой паттерн проектирования приложений – presenter (презентер). Это модуль который знает о модели и шаблоне.

Пример простого контроллера и шаблона, до внедрения презентера.

Контроллер

Модель

Шаблон

Внедрение презентера простое в папку App – добавьте папку presenters/post , файл index_presenter.rb

Содержимое презентера предельно простое:

Обновлённый контроллер

Обновлённый шаблон

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

rubynotes

База

  • Базовые типы данных в ruby: Fixnum, Bignum, Float, Array, String, Hash.
  • В руби всё объекты, например число 1 – это объект класса Fixnum (проверка 1.class).
  • Каждый объект имеет уникальный object_id, например 1.object_id.
  • Каждый класс имеет набор методов, например 1.to_f. Существуют методы классы и методы объекта.
  • Применяя * к строке, например “John” * 5 , вы на строке “John” используете метод *, с аргументом 5. Иначе говоря “John” * 5 == “John”.*(5)
  • Если вызвать у объекта несуществующий метод, то получим ошибку #, а вот у строки такой метод есть 40.to_s.reverse
  • Скобки при вызове метода необязательны.
  • Метод gsub проходит по всей строке и заменяет одну подстроку, на другую – ‘I\’m a senior developer’.gsub(‘senior’, ‘junior’).
  • Есть ряд методов которые вызываются без объекта, например puts, но объект просто опущен, так как используется корневой объект Kernel.
  • Методы с ! на конце меняют оргинальный объект, а методы с ? на конце – это так называемые предикаты, которые по соглашению возвращают булевое значение.
  • Хэши posts = {:title => ‘Заголовок’, ‘content’ => ‘Содержание статьи’ } эквивалент posts = {title: ‘Заголовок’, ‘content’ => ‘Содержание статьи’}. Краткая запись title: ‘Заголовок’, доступна только тогда когда ключом является символ , доступ к элементам хэша

Continue reading “rubynotes”

Docker геттинг стартед

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

Установка довольно проста, только как оказалось 32-х разрядные системы не поддерживаются. Для Mac или Windows необходимо просто скачать и установить Docker Toolbox. После установки проверьте в консоли

Continue reading “Docker геттинг стартед”

Links to like

LinksToLike – это один из проектов над которыми я недавно работал. В качестве хобби-проектов или коммерческих, но не попадающих в мой основной профессиональный профиль. О паре проектов я хочу рассказать.
Continue reading “Links to like”

SSRS – Stupid simple rails server

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

В качестве сервера Debian 8 64 bit, приложение на Rails 5 и база данных конечно Postgres.
Continue reading “SSRS – Stupid simple rails server”

Javascript роутер в 90 строк

Перевод статьи A modern JavaScript router in 100 lines

Требования:
Роутер должен:

  1. содержать меньше 100 строк
  2. поддерживать url с хэшами
  3. работать с History API
  4. предоставлять простой API интерфейс
  5. запускаться вручную
  6. отрабатывать только в тех случаях когда это необходимо

Continue reading “Javascript роутер в 90 строк”

Использование WebP в быту

WebP формат графических файлов разработанный Google и впервые представленный в 2010 году. Преимущества перед png\jpg может достигать 30% в весе файла, при том же качестве изображения. К сожалению, и поддерживается пока только в Chrome, и браузерах основанных на том же движке рендера, например Opera, или штатный браузер в Android. Несмотря на поддержку только в Chrome, всего выходит ~67% от общего числа пользователей, неплохо. Преимущества webp для сайтов просты, меньше вес изображений – быстрее загрузка сайта.
Continue reading “Использование WebP в быту”

Увеличение SVG без увеличения ширины линий

При увеличении размеров svg изображений соразмерно и увеличивается обводка (stroke). Такое поведение является стандартным, но его можно переопределить при помощи свойства vector-effect со значением non-scaling-stroke.

Ниже пример svg без этого свойства, и с ним.

See the Pen SVG scale without scaling strokes by Maksim R (@Rukomoynikov) on CodePen.

Краткий конспект по скринкасту Webpack от Ильи Кантора

Вынести модуль в глобальный доступ к модулю
Экспортировать сам модуль, и в секции output добавить library: ‘имя модуля для внешнего доступа’

Например, файл messenger

и конфиг для webpack, который добавит модули в глобальную область видимости window.messenger(‘Don’t drink to much alcohol’)

aggregateTimeout
По-умолчанию webpack ждёт 300 милисекунд после изменения файла, чтобы запустить пересборку. Но, это можно изменить – в конфиге укажите wathcOptions : {aggregateTimeout: 100}

Карты кода
За создание source-maps для модулей отвечает настройка devtool. Пример, devtool : ‘source-map’ – будет создан файл имя-модуля.js.map Есть и другие способы генерации source-map, главное отличие – применимость для “боевой” среды.

Переменные среды
Во время разработки есть необходимость переключаться между средами применения модулей. Например development\production, и во время development опция watch должна быть включена, а во генерации сборки для production соответственно выключена. Для этого можно использовать переменные среды. Укажите в конфиге webpack:

Теперь запустите webpack командой NODE_ENV=production webpack убедитесь, что webpack собрал модули и завершил работу. В отличие от запуска без NODE_ENV=production когда webpack продолжит следить за изменениями в файлах.

Переменные окружения в скриптах
При помощи переменных среды и webpack можно так же управлять и скриптами, часто вы используете console.log или debugger ? И хочется чтобы эти строки включались только в development среде.

Теперь можно заменить в модулях код, на что-то такое:

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

Краткий итог, EnvironmentPlugin для управления настройками webpack в зависимости от среды. DefinePlugin для передачи произвольных переменных в скрипты.

ES6 и Babel
В Chrome 50 уже практически все нововведния из ES6 поддерживаются без поддержки транспилеров типа Babel. К сожалению, такая ситуация не везде, и для того чтобы писать код на ES6, а работать он мог в любом браузере и работать одинаково нужно использовать Babel. Установите его:

В Webpack есть понятие лоадеров, загрузчиков. Это простые javascript функции которые могут вмешиваться в сборку модулей. Настройка загрузчика Babel в webpack.config.js

Resolving, поиск модулей и загрузчиков
Для того чтобы понять как webpack ищет модули надо разобрать две секции конфига webpack, это resolve и resolveLoader. Первая опция служит для общего поиска модулей, например для entry самого конфига, когда вы импортируете модули внутри скриптов.

Так webpack будет искать модуль home в папке node_modules, потом файл home.js

А resolveLoader, работает по похожему принципу, но с дополнительной опцией moduleTemplates, которая определяет возможные комбинации для именования папок:

UglifyJsPlugin
Для минификации и подготовки сборки для production используется UglifyJsPlugin обёртка. Его конечно надо включать только во время сборки файлов для production.

Другие опции для плагина, на сайте самого плагина UglifyJS – https://github.com/mishoo/UglifyJS2#usage

Несколько точек входа
Для этого в качестве entry необходимо использовать объект, ключами которого являются название модуля, а значением файл. В output добавить path, если ещ> не сделано, и в качестве filename шаблон.

Общие участки кода в один файл
Как это работает, у нас есть несколько точек входа, и каждая точка входа использует общие модули, например “домашняя страница” home.js и страница “о нас” about.js обе делают import welcome from ‘./welcome’ Таки общие участки можно выделить в отдельный файл при помощи CommonsChunkPlugin.
Код который необходим на всех страницах сайта. Простое подключение – забирает те модули которые содержатся во всех точках входа.

Так в файл common.js попадут все общие участки из точек входа.

Настройки CommonsChunkPlugin

minChunks – в каком количестве модулей должен присутствовать общий код чтобы быть вынесенным в отдельный файл. Это значит, что если у вас 10 точек входа, а общий код есть только в 9, то он не будет вынесен в отдельный файл. Но при настройке minChunks : 9 код попадёт в отдельный файл.
chunks – явное указание в каких точках входа искать общие модули, chunks : [‘home’, ‘about’]

В plugins можно указать несколько раз CommonsChunkPlugin, например

Информация о модулях – webpack –display-modules -v