Я исхожу из того, что вы уже минимально знакомы с RoR и что-то пытались на нем делать. Этот материал будет интересен простейшей аутентификацией пользователя посредством OpenID, а также тем, кто давно хотел попробовать MongoDB, но не знал с чего начать.
Мы будем использовать:
-O отказываемся от использования ActiveRecord (Mongoid вместо него)
-G отказываемся от гит (я использую Mercurial)
-T отказываемся от тестов
Правим Gemfile, приводя его к такому виду:
Тут мы добавляем необходимые нам гемы и указываем библиотеки для компиляции JS в зависимости от платформы. therubyracer считается быстрее, но есть проблемы с его компиляцией под win, поэтому мы используем движок Мозиллы.
Генерируем конфиг для MongoDB
rails g mongoid:config
Если вы хотите использовать систему контроля версий, то я рекомендую Mercurial. На мой взгляд она делает все тоже, что и Git, только проще и логичнее.
Нам понадобиться создать в корне файл .hgignore, чтобы исключить из-под контроля временные и часто изменяющиеся файлы:
Затем выполнить команды:
-A добавляет все новые файлы под контроль
-m что комментарий к коммиту передается в командной строке.
rails g model User openid_identity openid_data:hash status
Это создаст нам модель app/models/user.rb, приведем ее к виду:
include Mongoid::Timestamps добавляет привычные нам из AR created_at и updated_at
rails g scaffod Project title body budget time
К модели добавим строчки:
Также я внес изменения во вьюхи, их можно будет посмотреть в репозитарии.
Регистрации как таковой у нас не будет, вход только через OpenID через Loginza. Для этого мы подключим скрипт по адресу loginza.ru/js/widget.js.
app/views/layouts/application.html.slim:
А для вызова виджета будем использовать вот такую ссылку:
localhost:3000/signin — это адрес куда логинза перенаправит пользователя после входа
providers_set — список разрешенных провайдеров для входа.
Контроллер для обработки:
rails g controller sessions:
Здесь мы с помощью библиотеки net/http запрашиваем данные о пользователе с помощь токена, который нам передала Loginza POST запросом на /signin. TODO: необходимо сделать обработку ошибок (Loginza может вернуть ошибку, а тут это не учтено).
Затем пользователь с соответствующим OpenID находится в базе или создается новый, а в сессию записывается id пользователя.
В остальном механизм сессий идентичен описанному в Rails Tutorial. Советую обратить внимание на файл sessions_helper.rb и на добавление его методов в application_controller.rb
Этот код интересен тем, что я использую InheritedResources Этот гем берет на себя стандартные CRUD действия для объекта. create!, show! — это вызов хелперов этого гема. Советую сходить по ссылке, там подробные примеры как это можно использовать. Ну и before_filter для ограничения доступа к созданию проекта и его редактирования.
В app/views/projects/show.html.slim я вывожу OpenID автора
Вот такая доска объявлений с минимальным функционалом у нас получилась. Нам еще нужна админка, отклики и отзывы, профили и многое много другое. Но это вполне может быть первым маленьким шагом для большой компании.
Я опустил некоторые правки, которые посчитал не существенными поэтому вам может понадобится репозиторий bitbucket.org/nleo/lancemine
Перевод документации по RoR
Ruby on Rails Tutorial: Изучение Rails на Примерах
InheritedResources
Mongoid
Мы будем использовать:
- Ruby on Rails 3.2.8
- Slim
- Mongoid
- Loginza
Создание проекта
rails new lancemine -O -G -T
-O отказываемся от использования ActiveRecord (Mongoid вместо него)
-G отказываемся от гит (я использую Mercurial)
-T отказываемся от тестов
Правим Gemfile, приводя его к такому виду:
source 'https://rubygems.org' gem 'rails', '3.2.8' gem 'inherited_resources' gem 'slim-rails' gem 'mongoid' group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' gem 'therubyrhino', :platforms => :mswin gem 'therubyracer', :platforms => :ruby gem 'execjs' gem 'uglifier', '>= 1.0.3' end gem 'jquery-rails'
Тут мы добавляем необходимые нам гемы и указываем библиотеки для компиляции JS в зависимости от платформы. therubyracer считается быстрее, но есть проблемы с его компиляцией под win, поэтому мы используем движок Мозиллы.
bundleГенерируем конфиг для MongoDB
rails g mongoid:config
Mercurial
Если вы хотите использовать систему контроля версий, то я рекомендую Mercurial. На мой взгляд она делает все тоже, что и Git, только проще и логичнее.
Нам понадобиться создать в корне файл .hgignore, чтобы исключить из-под контроля временные и часто изменяющиеся файлы:
db/schema.rb config/mongoid.yml .bundle tmp Gemfile.lock syntax: glob db/*.sqlite3 log/*.log public/uploads/* public/assets/* *.swp *.orig *~
Затем выполнить команды:
hg init hg ci -Am "Init"
-A добавляет все новые файлы под контроль
-m что комментарий к коммиту передается в командной строке.
Модель пользователя
rails g model User openid_identity openid_data:hash status
Это создаст нам модель app/models/user.rb, приведем ее к виду:
class User include Mongoid::Document include Mongoid::Timestamps field :openid_identity, type: String field :openid_data, type: Hash field :status, type: String has_many :projects end
include Mongoid::Timestamps добавляет привычные нам из AR created_at и updated_at
Проекты
rails g scaffod Project title body budget time
К модели добавим строчки:
include Mongoid::Timestamps belongs_to :user
Также я внес изменения во вьюхи, их можно будет посмотреть в репозитарии.
Сессии
Регистрации как таковой у нас не будет, вход только через OpenID через Loginza. Для этого мы подключим скрипт по адресу loginza.ru/js/widget.js.
app/views/layouts/application.html.slim:
doctype html html head title Lancemine = stylesheet_link_tag "application", :media => "all" = javascript_include_tag "application" script src="http://loginza.ru/js/widget.js" type="text/javascript"
А для вызова виджета будем использовать вот такую ссылку:
loginza.ru/api/widget?token_url=#{u 'http://localhost:3000/signin'}&providers_set=vkontakte,facebook,livejournallocalhost:3000/signin — это адрес куда логинза перенаправит пользователя после входа
providers_set — список разрешенных провайдеров для входа.
Контроллер для обработки:
rails g controller sessions:
class SessionsController < ApplicationController require 'net/http' require 'json' def create openid_data = params[:token] openid_data = Net::HTTP.get(URI.parse("http://loginza.ru/api/authinfo?token=#{params[:token]}")) openid_data = JSON.parse openid_data user = User.find_or_create_by(openid_identity: openid_data['identity']) if user.status != 'banned' user.openid_data = openid_data user.save session[:user_id] = user.id redirect_to root_url, :notice => "Logged in!" else redirect_to root_url, :notice => "You blocked!" end end def destroy session[:user_id] = nil redirect_to root_url, :notice => "Logged out!" end end
Здесь мы с помощью библиотеки net/http запрашиваем данные о пользователе с помощь токена, который нам передала Loginza POST запросом на /signin. TODO: необходимо сделать обработку ошибок (Loginza может вернуть ошибку, а тут это не учтено).
Затем пользователь с соответствующим OpenID находится в базе или создается новый, а в сессию записывается id пользователя.
В остальном механизм сессий идентичен описанному в Rails Tutorial. Советую обратить внимание на файл sessions_helper.rb и на добавление его методов в application_controller.rb
Контроллер проектов
class ProjectsController < InheritedResources::Base before_filter :signed_in_user, except: [:show, :index] before_filter :correct_user, only: [:update, :edit, :destroy] def show @project = Project.find params[:id] @author = @project.user.id == current_user.id if signed_in? show! end def create @project = Project.new params[:project] @project.user = current_user create! end def index @projects = Project.order_by(:created_at.desc) end private def correct_user @project = current_user.projects.find(params[:id]) redirect_to root_url if @project.nil? end end
Этот код интересен тем, что я использую InheritedResources Этот гем берет на себя стандартные CRUD действия для объекта. create!, show! — это вызов хелперов этого гема. Советую сходить по ссылке, там подробные примеры как это можно использовать. Ну и before_filter для ограничения доступа к созданию проекта и его редактирования.
В app/views/projects/show.html.slim я вывожу OpenID автора
Соответственно, если исполнителя заинтересует проект, он может свзязаться с заказчиком через его профиль на Facebook, VKontakte или LiveJournal.= link_to @project.user.openid_identity, @project.user.openid_identity
Вот такая доска объявлений с минимальным функционалом у нас получилась. Нам еще нужна админка, отклики и отзывы, профили и многое много другое. Но это вполне может быть первым маленьким шагом для большой компании.
Я опустил некоторые правки, которые посчитал не существенными поэтому вам может понадобится репозиторий bitbucket.org/nleo/lancemine
Перевод документации по RoR
Ruby on Rails Tutorial: Изучение Rails на Примерах
InheritedResources
Mongoid
