Показ дописів із міткою datamapper. Показати всі дописи
Показ дописів із міткою datamapper. Показати всі дописи

вівторок, 22 травня 2012 р.

CarrierWave з DataMapper у Sinatra

У вільний час займаюся розробкою веб-додатку на Sinatra з використанням DataMapper. І ось задався питанням завантаження аватарів на сервер та їх після-обробкою.

Переглянувши доступні інструменти для забезпечення цієї функціональності, вибір впав на бібліотеку CarrierWave, яка на відміну від більшості інших не зав'язана на Rails/ActiveRecord.

CarrierWave описує себе, як "першокласне рішення для завантаження файлів для Rails, Sinatra та інших веб-додатків на основі Rack". Проект був започаткований у серпні 2008 року, і перший випуск відбувся в березні 2009 року. Перша його назва була Merb::Upload і він був без підтримки Rails.

Той факт, що CarrierWave почав своє життя в якості плагіна для Merb може пояснити його модульність, гнучкість і розширюваність.

Завдяки fog, він має підтримку Amazon S3, Rackspace Cloud Files і Google Storage for Developers. Він також підтримує звичайне зберігання файлів і GridFS в MongoDB.
Має підтримку незліченної кількості ORM: ActiveRecord, Mongoid, DataMapper, Sequel, MongoMapper, CouchDB.
Обробка зображення доступна засобами RMagick, ImageScience або MiniMagick.
Сама по собі ця бібліотека дуже добре документована, і якщо раптом когось цікавлять деталі, то читайте wiki.

У цій статті для прикладу ми напишемо просту фотогалерею.
Наступні gem`и повинні бути встановлені:
  • sinatra
  • datamapper
  • dm-sqlite-adapter
  • slim
  • carrierwave - для завантаження зображень
  • carrierwave-datamapper - для зв'язку DataMapper і CarrierWave
  • rmagick - для створення мініатюр зображень(в Ubuntu потрібно встановити пакет libmagick++-dev)

вівторок, 21 лютого 2012 р.

OmniAuth Identity з DataMapper в Sinatra

З виходом OmniAuth версії 1.0 з'явилася нова стратегія Identity, яка дозволяє використовувати традиційну аутентифікацію по логіну і паролю.

Раніше я вже писав про OmniAuth - раз і два.

У цій статті ми познайомимося з стратегією під назвою Identity, яка дозволяє користувачу створити обліковий запис, вказавши ім'я користувача та пароль, замість входу через зовнішнього постачальника.

Вихідний код цієї статті заснований на OmniAuth для Sinatra, і якщо ви не знайомі з OmniAuth цю статтю варто прочитати в першу чергу.

понеділок, 13 лютого 2012 р.

Налаштування will_paginate для Bootstrap у Sinatra

Нещодавно вийшла друга версія популярного HTML-фреймворка Bootstrap. Для тих хто не в курсі що це, настійно рекомендую ознайомитися. Цей набір дозволяє створювати шаблони сайтів за лічені години(перевірено на власному досвіді) на основі готових наборів стилів, які різко спрощують розстановку елементів на сторінці та забезпечують якісну типографію.

Крім того вийшла версія will_paginate 3.0.3, у яку крім усього іншого також ввійшов коміт, що виправляв кілька багів пов'язаних з DataMapper.
І у зв'язку з цієї радісною новиною, я вирішив прикрутити пагінацію до свого проекту на Sinatra, у якому, як ви вже мабуть здогадалися використовується Bootstrap.

Підключаємо необхідні бібліотеки:
require 'will_paginate'
require 'will_paginate/data_mapper'

Вказуємо will_paginate генерувати теги у стилі Bootstrap:
class BootstrapLinkRenderer < ::WillPaginate::Sinatra::LinkRenderer
  protected
  
  def html_container(html)
    tag :div, tag(:ul, html), container_attributes
  end

  def page_number(page)
    tag :li, link(page, page, :rel => rel_value(page)), :class => ('active' if page == current_page)
  end

  def gap
    tag :li, link(super, '#'), :class => 'disabled'
  end

  def previous_or_next_page(page, text, classname)
    tag :li, link(text, page || '#'), :class => [classname[0..3], classname, ('disabled' unless page)].join(' ')
  end
end

І на останок пишемо помічник, який дозволить виводити навігацію у простій формі:
== page_navigation_links @events

helpers do

  def page_navigation_links(pages)
    will_paginate(pages, :class => 'pagination', :inner_window => 2, :outer_window => 0, :renderer => BootstrapLinkRenderer, :previous_label => '&larr;', :next_label => '&rarr;')
  end

end

вівторок, 13 грудня 2011 р.

Асоціації в DataMapper

Прочитавши заголовок цієї статті, читач мабуть зрозуміє про що піде мова нижче. У далекому 2009 я писав статтю про DataMapper, у якій згадувались асоціації між моделями. Сьогодні з власного досвіду спробую описати найбільш поширені асоціації та роботу з ними.
Для початку освіжимо пам'ять.
DataMapper - це ORM бібліотека (англ. Object-relational mapping, Обє'ктно-реляційна проекція - технологія, яка зв'язую бази даних з концепцією об'єктно-орієнтовного програмування, створюючи "віртуальну об'єктну базу даних").

Асоціації - це спосіб оголошення відносин між моделями. Вони надають ряд методів, які дозволяють створювати відносини та отримувати пов'язані моделі.

Зараз ORM використовуються повсюдно - ніхто не намагається працювати з базою вручну. Функціонал дозволяє зробити багато речей простіше. Робота з асоціаціями стала в рази легшою. Можна не використовувати SQL-запити, а працювати з даними, як зі звичайними об'єктами.

Я писав цю статтю виключно для себе, тому методика викладання навряд чи сподобається вам своєю легкістю і доступністю :))
Картинка для затравки.
Зацікавило? Тоді ласкаво прошу під кат.

середа, 26 жовтня 2011 р.

Модель User в DataMapper(з BCryptHash) для Warden

В процесі написанні статті Модель User в DataMapper для Warden я натрапив на цікавий тип даних BCryptHash. В DataMapper він стає доступний, якщо включити гем dm-types. BCryptHash зберігається у базі даних як рядок, що представляє сіль, хеш і вартість паролю, використовуючи алгоритм bcrypt. Він пропонує альтернативу більш звичної пари значень хеш і сіль, які зберігаються у базі даних.

Модель User в DataMapper для Warden

В минулій статті Інтеграції Warden з Sinatra і DataMapper ми написали тестовий додаток, який використовує аутентифікацію по імені і паролю. Уважний читач не міг не помітити, що паролі у базі даних зберігаються у відкритому вигляді. Це все робилося, щоб не завантажувати статтю зайвими сутностями.
Але очевидно, з точки зору безпеки паролі у базі даних повинні зберігатися в зашифрованому вигляді. Цю тему ми і розглянемо у цій статті.

За основу взята 11 глава "Task F: Administration" з книги Agile Web Development with Rails (3rd edition).

Тут основний упор буде на роботу з DataMapper. Крім того у другій частині статті ми закладемо фундамент адміністративного інтерфейсу для керування користувачами.

понеділок, 24 жовтня 2011 р.

Інтеграції Warden з Sinatra і DataMapper

В Інтернеті можна знайти багато статей на тему аутентифікації з допомогою Warden у Sinatra. Я не буду оригінальним, і напишу ще одну, щоб самому розібратися з особливостями цього інструменту. Ціллю цієї статті не є показати повністю готовий механізм аутентифікації. А лише продемонструвати основні можливості інтеграції Warden з Sinatra і Datamapper.

Warden - це Rack middleware, що забезпечує механізм аутентифікації для веб-додатків на Ruby.
Warden вимагає деяких налаштувань для Sinatra. Цього можна уникнути, використовуючи плагін Sinatra::Warden. Але ми ж не шукаємо простих шляхів.

вівторок, 4 жовтня 2011 р.

Приклад роботи Delayed_job з DataMapper у Sinatra

Delayed_job (або DJ) бібліотека асинхронної черги фонових завдань написана на Ruby. Може знадобитись для таких типових задач як:
  • поштова розсилка
  • зміна розмірів зображень
  • конвертування аудіо/відео
  • HTTP завантаження
  • оновлення інформації
  • перевірка спаму
Спочатку написана Tobias Lütke як плагін для веб-фреймворка Rails з Active Record. На даний час підтримується компанією Collective Idea, і дозволяє використовувати ряд інших бекендів для збереження черги завдань.

пʼятниця, 2 вересня 2011 р.

will_paginate 3.0: Sinatra і DataMapper

Після більше року розробки вийшла фінальна версія will_paginate 3.0. Основні зміни:
  • Підтримка Rails 3.0 і 3.1
  • Підтримка Sinatra і Merb
  • Інтеграція з DataMapper і Sequel
  • Переклад із бібліотекою i18n
  • Припинена підтримка Rails версій 1.2 - 2.3
Встановлення:
gem install will_paginate
Sinatra додаток потребує наступні бібліотеки:
require 'will_paginate'
require 'will_paginate/data_mapper'  # або active_record/sequel
Вносимо зміни до дії index, щоб виводити по 5 записів на сторінку. Номер сторінки передаватиметься у рядку запиту (наприклад, http://localhost:4567/posts?page=3)
# index
get "/posts" do
  @posts = Post.paginate :page => params[:page], :per_page => 5
  haml :"posts/index"
end
Додаємо помічник will_paginate для виведення посилань на сторінки:
#header
  %h1 Мій блог

%a{:href => "posts/new"}> New Post
#content
  - @posts.each do |post|
    .container
      %h3= post.title
      %p= post.body
      %p= post.created_at

  #pagination
    = will_paginate @posts

понеділок, 1 серпня 2011 р.

OmniAuth для Sinatra

Про швидкий запуск Sinatra додатку, використовуючи OmniAuth, як протокол автентифікація я писав у OmniAuth: Зовнішня, проста автентифікація для Rack на прикладі Sinatra і ВКонтакте. Код цієї статті відрізняється від попередньої тим, що включає в себе роботу з сесіями і модель для користувачів у базі даних. Це означає, що користувач може залишатися в системі, поки ваш сервер залишається живим.

Для прикладу використовуватимемо ВКонтакте. Але ви можете використовувати будь-якого іншого постачальника аутентифікації, що підтримується бібліотекою OmniAuth.

пʼятниця, 17 червня 2011 р.

Використання will_paginate з DataMapper і Sinatra

Часто потрібно так, щоб у представлені(View) відображалися не усі записи з масиву на одній сторінці. У цьому випадку необхідно реалізувати розбиття на сторінки(pagination). Забезпечення цієї функціональності буде простішим з використанням плагіна WillPaginate, який є популярним у середовищі Rails-розробників. У цій статті мова піде про використання WillPaginate разом з Sinatra і DataMapper. Все що нам потрібно це версія >3.0 з підтримкою DataMapper.

Здійснюємо пошук
$ gem search will_paginate --remote
і встановлюємо необхідну версію
$ sudo gem install agnostic-will_paginate

За приклад ми візьмемо наш проект блогу із серії статей про Sinatra. Нашою задачею буде вивести на головну сторінку статті з розбивкою по сторінках.

четвер, 26 травня 2011 р.

Огляд Padrino і OmniAuth

У цій статті буде показано, як з’єднати модуль автентифікації Access Control, описаний тут, з OmniAuth middleware для Rack.

Система аутентифікації і контролю доступу Padrino забезпечує простий спосіб створювати свої системи аутентифікації. У поєднанні з OmniAuth ви можете легко використовувати її для аутентифікації за допомогою різних методів. Читайте нижче для більш докладної інформації про те, як інтегрувати їх.

У цій статті ми розглянемо дві теми:
  • Інтеграцію Padrino Admin Authentication в усі додатки вашого проекту
  • Створення власних стратегій аутентифікації

На відміну від оригінальної статті, де у якості ORM використовується ActiveRecord, тут ми будемо використовувати DataMapper, про який я писав тут. Можливо вам необхідно познайомитись з фреймворком Padrino, про який я писав тут і тут. І про OmniAuth тут.

Перш ніж ми почнемо, важливо відзначити, що наша вбудована аутентифікація, що базується на ролях, може взаємодіяти з іншими системами. Потрібно лише внести зміни у файли session.rb і account.rb для того щоб додати свій власний код.

Отже, давайте почнемо зі створення проекту використовуючи DataMapper:

середа, 5 травня 2010 р.

Meet Padrino! Part 2

У попередній статті ми познайомитись з веб-фреймворком Padrino. Створили проект і розглянули його структуру. Також навчились генерувати інтерфейс адміністратора, контролери і моделі. Сьогодні ми продовжимо наше знайомство з цим чудовим фреймворком.
Минулого разу ми додали можливість керувати(створювати, редагувати і видаляти) повідомленнями блогу і відображати їх на головній сторінці. Але ми пропустили одну важливу властивість у моделі Post - дату створення/редагування повідомлення.

пʼятниця, 23 квітня 2010 р.

Meet Padrino! Part 1

Днями по гарячих слідах Sinatra 1.0 вийшов офіційний реліз Padrino. Цю статтю я почав писати відразу після виходу версії 0.9.9 (2 квітня), але з технічних причин зумів довести її до кінця тільки після виходу 0.9.10 (22 квітня).

Padrino - це ще один веб-фреймворк, написаний на мові Ruby. Padrino намагається зробити розробку додатків більш простою і елегантною настільки наскільки це можливо, шляхом розширенням функціональності Sinatra (додаючи помічники, генератори, інтерфейс адміністратора, інтернаціоналізацію), зберігаючи його дух.
Я вже писав декілька статей про Sinatra, думаю їх буде корисно почитати.

Отже, зустрічайте – Padrino!

субота, 28 листопада 2009 р.

RESTful Sinatra

Попередні статті:
  1. Привіт, Sinatra!
  2. Привіт, DataMapper!
  3. Співаємо з Sinatra!

Прийшов час поговорити про REST архітектуру додатку та її реалізацію на Sinatra.
Особисто мені коштувало багато зусиль зрозуміти, що таке REST. Тому прошу не чіплятися до того, наскільки я спрощую термінологію, щоб сфокусуватися на самій темі.
REST - це Representational State Transfer, так звана "передача стану представлення". Фактично - це спосіб організації доступу до ресурсів. Відповідно до цієї архітектури використовується чотири типи HTTP запитів - GET, POST, PUT і DELETE.
  • GET - отримати ресурс тільки для читання
  • POST - створити новий ресурс
  • PUT - оновити існуючий ресурс
  • DELETE - видалити ресурс

Нічого не нагадує? Якщо порівняти з SQL-синтаксисом, GET - це запит SELECT, POST - це INSERT, PUT - UPDATE, і DELETE - знову просто DELETE.
Ресурси - це ті дані, з якими ми працюємо. Наприклад у нашому блозі стаття - це ресурс, коментарій - це теж ресурс. Ресурси можуть мати взаємозв'язки, та містити в собі інші ресурси. Для більшості ресурсів в нашому додатку будуть необхідні операції їх створення, отримання, оновлення та видалення.

Крім звичних GET і POST Sinatra розуміє методи PUT і DELETE. Нажаль ці методи не підтримуються броузерами, але Sinatra вміє з ними працювати через прихований елемент форми з ім'ям "_method" і значенням, рівним методу HTTP: put або delete. Наприклад:
<form method="post" action "/destroy">
  <input type="hidden" name="_method" value="delete">
  <button type="submit">Destroy it</button>
</form>

Далі ми будемо вважати клас-контролер реалізацією інтерфейсу REST.
Наш контролер буде реалізовувати наступні сім дій(методів).
Чотири цих:
  • show: обробляє GET запит для відображення індивідуального ресурсу, який ідентифікується виразом params[:id]
  • create: обробляє POST запит для створення нового екземпляру ресурсу
  • update: обробляє PUT запит для оновлення існуючого ресурсу, ідентифікованого виразом params[:id], використовуючи дані зв'язані з запитом
  • destroy: обробляє DELETE запит для видалення екземпляра ресурсу, ідентифікованого виразом params[:id]

І три цих:
  • index: обробляє GET запит для відображення колекції ресурсів
  • new: обробляє GET запит, який створює логічну структуру нового ресурсу і передає її клієнту. Цей ресурс не буде збережений на сервері. Можна вважати, що дія new створює порожню форму, яка передається клієнту для заповнення.
  • edit: обробляє GET запит, який повертає вміст ресурсу, ідентифікованого виразом params[:id], в форму, пристосовану для редагування цього вмісту

Не важко помітити, що ці сім дій включають чотири базових операції для створення, читання, оновлення і видалення ресурсу - CRUD (create, read, update, delete). Серед них також є дії для виводу переліку ресурсів та дві додаткові дії, які повертають клієнту новий та існуючий ресурси в форму, призначену для редагування.

Для Sinatra назви цих дій не мають ніякого значення, і використовуються мною тільки для зручності, і є запозиченими з Rails.
Для того щоб реалізувати REST підхід у нашому додатку треба поступити інакше ніж у попередній статті. В першу чергу один і той же URL може в залежності залежати від типу HTTP запиту відповідати різним методам. Наприклад URL
/posts/1
повинен викликати метод show(для відображення статті №1), якщо був використаний запит GET, але у випадку запиту DELETE повинен викликати метод destroy.


Все що нам залишилося зробити, це реалізувати цих сім методів у нашому контролері і оновити шаблони представлень.

понеділок, 23 листопада 2009 р.

Співаємо з Sinatra!


Ця стаття є так би мовити третьою. У двох попередніх ми вже встигли познайомитися з веб-фреймворком Sinatra (Привіт Sinatra!) та ORM бібліотекою DataMapper (Привіт DataMapper!). Прийшов час застосувати ці знання на практиці. Напишемо наш "proof of concept" додаток, використовуючи Sinatra, DataMapper, HAML, SASS. Я вирішив, що ми проведемо наші навчальні заняття за написанням блогу.

Sinatra не піклується про те, як ви організовуєте ваш додаток. На відміну від Rails, Sinatra не накладає ряд серйозних обмежень на структуру ваших додатків. Ви можете покласти все в один файл, або розбити на структуру каталогів. Звичайно, якщо ви розіб'єте на окремі файли, потрібно підключати їх в міру необхідності - у Sinatra немає узгоджень, як в Rails, про те де шукати ці файли.
Моя структура каталогів, вона дуже проста:
/
  blog.rb
  db/
    db.sqlite3
  views/
    layout.haml
    /posts
      edit.haml
      index.haml
      new.haml
      show.haml

Я поклав все крім шаблонів в один файл. Таким чином конфігурації, моделі і всі події будуть у файлі blog.rb. Також Sinatra по замовчуванню підхоплює каталог views, який містить шаблони представлень.

понеділок, 9 листопада 2009 р.

Привіт, DataMapper!

DataMapper - це ORM бібліотека (англ. Object-relational mapping, Обє'ктно-реляційна проекція - технологія, яка зв'язую бази даних з концепцією об'єктно-орієнтовного програмування, створюючи "віртуальну об'єктну базу даних"). DataMapper написана на Ruby, і широко використовується у таких фреймворках як Merb та Sinatra. Вона була розроблена, щоб усунути недоліки бібліотеки ActiveRecord, яка використовується в Ruby on Rails по замовчуванню. DataMapper слідує стандартам ORM-моделі: таблиці відображаються у вигляді класів, записи - у вигляді об'єктів, а стовпці - у вигляді властивостей цих об'єктів. Методи класу використовуються для здійснення операцій на рівні таблиці, а методи екземпляра здійснюють операції над окремими рядками.
Якщо в базі даних є таблиця з назвою posts (записи), то наш застосунок матиме клас Post. Рядки цієї таблиці відповідають об'єктам класу - конкретний запис представляється як об'єкт класу Post. У межах цього об'єкту для отримання доступу до окремих стовпців і встановлення їм значення, використовуються властивості.

Інсталяція DataMapper

DataMapper доступний через менеджер пакетів Ruby Gem:
gem install dm-core

Якщо ви плануєте використовувати DataMapper з базою даних, встановіть адаптер бази даних з проекту DataObjects. В залежності від ваших уподобань, це може бути do_mysql, do_postgres або do_sqlite3.
gem install do_sqlite3