
Наверное каждый в начале работы с ROR был впечатлен возможностью Scaffolding'а, который позволяет одной командой создавать migrations, controllers, models и views.
Но что делать если в своем проекте вы используете не стандартные Rails утилиты: erb, Test::Unit, fixturies, а сторонние инструменты: Haml, Rspec, Cucumber, Factory Girl и более того, хотите добавить собственные шаблоны?
Интересно? GOTO next line.
Исходные данные:
Ruby on Rails; Rspec; will-paginate; Haml; Factory-girl
Задача:
% rails generate scaffold post post:string Генерирует:
- contoller's с поддержкой will_paginate, русскоязычными сообщениями
- model's с поддержкой will_paginate
- view's с заданным нами содержимым и в формате haml
- Rspec тесты, вместо Test::Unit
- Factory Girl factories вместо стандартных fixtures
Для начала коротко о Scaffold. Scaffold — это встроенный генератор, сам по себе он ничего не генерирует, но запускает другие генераторы.
Текущие настройки scaffold можно проверить с помощью:
% rails g scaffold --helpГенераторы настраиваются с помощью файла RAILS_ROOT/config/application.rb, внутри которого можно задавать параметры с помощью такой конструкции:
config.generators do |g| # настройки генераторов end
CUSTOM CONTROLLERS
Начнём с того, что заменим стандартный шаблон контроллеров на свой.
Необходимо скопировать шаблон из гема используемого в проекте в сам проект.
Путь до гемов вашего проекта можно узнать таким способом:
RAILS_ROOT% rails console
puts $LOAD_PATH
...
...
... тут следует список всех гемов с полными путямиСкопируем шаблон controller.rb из GEMS_PATH/railties[version]/lib/rails/generators/rails/scaffold_controller/templates в RAILS_ROOT/lib/templates/rails/scaffold_controller/controller.rb
#Вот так выглядит исходный шаблон контроллера controller.rb class <%= controller_class_name %>Controller < ApplicationController # GET <%= route_url %> # GET <%= route_url %>.xml def index @<%= plural_table_name %> = <%= orm_class.all(class_name) %> respond_to do |format| format.html # index.html.erb format.xml { render :xml => @<%= plural_table_name %> } end end ...
Немного кастомиризуем его, добавив поддержку русского языка, паджинацию и обрезав лишний текст
# encoding: UTF-8 class <%= controller_class_name %>Controller < ApplicationController # GET <%= route_url %> def index @<%= plural_table_name %> = <%= class_name %>.paginate :page => params[:page], :order => 'id DESC' end ...
После работы scaffold мы получим такой миловидный код
# encoding: UTF-8 class PostsController < ApplicationController # GET /posts def index @posts = Post.paginate :page => params[:page], :order => 'id DESC' end ...
CUSTOM MODELS
Скопируем файл шаблона model.rb с GEMS_PATH/activerecord[version]/lib/rails/generators/active_record/model/templates в RAILS_ROOT/lib/templates/active_record/model/model.rb
#Исходный код шаблона model.rb class <%= class_name %> < <%= parent_class_name.classify %> <% attributes.select {|attr| attr.reference? }.each do |attribute| -%> belongs_to :<%= attribute.name %> <% end -%> end
Добавим поддержку русского языка и 2 параметра для will_paginate
# encoding: UTF-8 class <%= class_name %> < <%= parent_class_name.classify %> cattr_reader :per_page @@per_page = 20 <% attributes.select {|attr| attr.reference? }.each do |attribute| -%> belongs_to :<%= attribute.name %> <% end -%> end
На выходе получаем:
# encoding: UTF-8 class Post < ActiveRecord::Base cattr_reader :per_page @@per_page = 20 end
CUSTOM VIEWS
В нашем примере мы используем HAML вместо .erb. Как заставить Rails генерировать не erb, a haml view's?
Очень просто, достаточно установить gem «haml-rails».
Дописываем в Gemfile
gem 'haml-rails'
И запускаем bundle install
Готово! Теперь рельсогенератор делает file_name.html.haml файлы для нас
Перейдём к нашим шаблонам. Скопируем 5 файлов (edit.html.haml, _form.html.haml, index.html.haml, new.html.haml, show.html.haml) из GEMS_PATH/haml-rails[version]/lib/generators/haml/scaffold/templates в уже полюбившуюся нам RAILS_ROOT/lib/templates/haml/scaffold
Не буду приводить здесь кода, его можно посмотреть по ссылкам ниже
Исходные шаблоны — haml-rails
Шаблон после редактирования — ссылка
Результат — ссылка
RSPEC
Как и в случае с haml, для замены стандартных тестов RSpec'овскими достаточно установить gem «rspec-rails».
По умолчанию scaffold будет создавать rspec файлы для тестирования моделей, контроллеров, хелперов, вьюх, роутинга и запросов.
Наверняка вам как и мне не нужно столько rspec файлов, к счастью ROR позволяет нам настроить этот пункт.
#RAILS_ROOT/config/application.rb config.generators do |g| #Здесь я отключил генерацию rspec файлов для вьюх, хелперов, роутинга и запросов #т.о. оставив лишь генерацию spec's для моделей и контроллеров g.test_framework :rspec, :view_specs => false, :helper_specs => false, :routing_specs => false, :request_specs => false end
FACTORY GIRL
Для добавления scaffolding для FG, установим gem «rails3-generators»
И добавим в конфиг следующую строчку
#RAILS_ROOT/config/application.rb config.generators do |g| g.test_framework :rspec, :view_specs => false, :helper_specs => false, :routing_specs => false, :request_specs => false g.fixture_replacement :factory_girl, :dir => "spec/factories" end
Помимо factory_girls гем «rails3-generators» добавляет генераторы для DataMapper, Authlogic, Mongomapper, Shoulda, Formtastic и SimpleForm
Что же у нас получилось?
% rails g scaffold final final:stringinvoke active_record
create db/migrate/20110713193843_create_finals.rb
create app/models/final.rb
invoke rspec
create spec/models/final_spec.rb
invoke factory_girl
create spec/factories/finals.rb
route resources :finals
invoke scaffold_controller
create app/controllers/finals_controller.rb
invoke haml
create app/views/finals
create app/views/finals/index.html.haml
create app/views/finals/edit.html.haml
create app/views/finals/show.html.haml
create app/views/finals/new.html.haml
create app/views/finals/_form.html.haml
invoke rspec
create spec/controllers/finals_controller_spec.rb
invoke helper
invoke rspec
invoke helper
create app/helpers/finals_helper.rb
invoke rspec
invoke stylesheets
identical public/stylesheets/scaffold.cssСобственные шаблоны для MVC; haml view's; factory_girl factories; RSpec's для моделей и контроллеров; встроенная паджинация.
Всё как мы хотели. Наслаждайтесь))
Посмотреть полный код
Github
Почитать
Generators manual
Paul's Barry Article: Customizing generators in rails 3
Rspec generators detail
Подкаст про генераторы
rails3-generators gem
haml-rails gem