После прочтения этого руководства, вы узнаете
Этот самоучитель предполагает, что вы обладаете знаниями основ Rails, которые можно почерпнуть в руководстве Rails для начинающих.
Сначала давайте создадим простое приложение на Rails с помощью команды rails new
.
Мы используем это приложение, чтобы попробовать все команды, описанные в этом руководстве.
Гем rails можно установив, написав gem install rails
, если вы еще этого не сделали.
rails new
Первым аргументом, который передается в команду rails new
, является имя приложения.
$ rails new my_app
create
create README.md
create Rakefile
create config.ru
create .gitignore
create Gemfile
create app
...
create tmp/cache
...
run bundle install
Rails создаст кучу всего с помощью такой маленькой команды! Теперь вы получили готовую структуру директории Rails со всем кодом, необходимым для запуска нашего простого приложения.
Если хотите пропустить какие-то файлы при генерации, или опустить некоторые библиотеки, можно добавить любые из следующих аргументов к команде rails new
:
Аргумент | Описание |
---|---|
--skip-git |
Пропустить git init, .gitignore и .gitattributes |
--skip-docker |
Пропустить Dockerfile, .dockerignore и bin/docker-entrypoint |
--skip-keeps |
Пропустить файлы для контроля версий .keep |
--skip-action-mailer |
Пропустить файлы Action Mailer |
--skip-action-mailbox |
Пропустить гем Action Mailbox |
--skip-action-text |
Пропустить гем Action Text |
--skip-active-record |
Пропустить файлы Active Record |
--skip-active-job |
Пропустить Active Job |
--skip-active-storage |
Пропустить файлы Active Storage |
--skip-action-cable |
Пропустить файлы Action Cable |
--skip-asset-pipeline |
Пропустить Asset Pipeline |
--skip-javascript |
Пропустить файлы JavaScript |
--skip-hotwire |
Пропустить интеграцию с Hotwire |
--skip-jbuilder |
Пропустить гем jbuilder |
--skip-test |
Пропустить файлы тестов |
--skip-system-test |
Пропустить файлы системных тестов |
--skip-bootsnap |
Пропустить гем bootsnap |
--skip-dev-gems |
Пропустить добавление гемов для разработки |
--skip-rubocop |
Пропустить настройку RuboCop |
Это только некоторые из опций, которые принимает rails new
. Для полного списка опций, напишите rails new --help
.
При создании нового приложения Rails, есть опция указать, какой вид базы данных собирается использовать ваше приложение. Это сэкономит вам несколько минут, и определенно много нажатий клавиш.
Давайте рассмотрим, что сделает для нас опция --database=postgresql
:
$ rails new petstore --database=postgresql
create
create app/controllers
create app/helpers
...
Давайте посмотрим, что она поместить в наш config/database.yml
:
# PostgreSQL. Versions 9.3 and up are supported.
#
# Install the pg driver:
# gem install pg
# On macOS with Homebrew:
# gem install pg -- --with-pg-config=/usr/local/bin/pg_config
# On Windows:
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem "pg"
#
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: petstore_development
...
Она сгенерировала конфигурацию базы данных, соответствующую нашему выбору PostgreSQL.
Имеется несколько команд, абсолютно критичных для повседневного использования в Rails. В порядке возможной частоты использования, они следующие:
bin/rails console
bin/rails server
bin/rails test
bin/rails generate
bin/rails db:migrate
bin/rails db:create
bin/rails routes
bin/rails dbconsole
rails new app_name
Список доступных команд rails, который часто будет зависеть от вашей текущей директории, можно получить, написав rails --help
. У каждой команды есть описание, это должно помочь найти то, что вам необходимо.
$ rails --help
Usage:
bin/rails COMMAND [options]
You must specify a command. The most common commands are:
generate Generate new code (short-cut alias: "g")
console Start the Rails console (short-cut alias: "c")
server Start the Rails server (short-cut alias: "s")
...
All commands can be run with -h (or --help) for more information.
In addition to those commands, there are:
about List versions of all Rails ...
assets:clean[keep] Remove old compiled assets
assets:clobber Remove compiled assets
assets:environment Load asset compile environment
assets:precompile Compile all the assets ...
...
db:fixtures:load Load fixtures into the ...
db:migrate Migrate the database ...
db:migrate:status Display status of migrations
db:rollback Roll the schema back to ...
db:schema:cache:clear Clears a db/schema_cache.yml file
db:schema:cache:dump Create a db/schema_cache.yml file
db:schema:dump Create a database schema file (either db/schema.rb or db/structure.sql ...
db:schema:load Load a database schema file (either db/schema.rb or db/structure.sql ...
db:seed Load the seed data ...
db:version Retrieve the current schema ...
...
restart Restart app by touching ...
tmp:create Create tmp directories ...
bin/rails server
Команда bin/rails server
запускает веб-сервер Puma, поставляемый с Ruby. Его будем использовать всякий раз, когда захотим увидеть свою работу в веб-браузере.
Безо всякого принуждения, bin/rails server
запустит наше блестящее приложение на Rails:
$ cd my_app
$ bin/rails server
=> Booting Puma
=> Rails 8.0.0 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.0 (ruby 3.1.3-p185) ("The Eagle of Durango")
* Min threads: 5
* Max threads: 5
* Environment: development
* PID: 5295
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
Всего лишь тремя командами мы развернули сервер Rails, прослушивающий порт 3000. Перейдите в браузер и зайдите на http://localhost:3000, вы увидите простое приложение, запущенное на rails.
Для запуска сервера также можно использовать псевдоним "s": bin/rails s
.
Сервер может быть запущен на другом порту, при использовании опции -p
. Среда по умолчанию может быть изменена с использованием -e
.
$ bin/rails server -e production -p 4000
Опция -b
привязывает Rails к определенному IP, по умолчанию это localhost. Можете запустить сервер, как демона, передав опцию -d
.
bin/rails generate
Команда bin/rails generate
использует шаблоны для создания целой кучи вещей. Запуск bin/rails generate
выдаст список доступных генераторов:
Также можно использовать псевдоним "g" для вызова команды generate
: bin/rails g
.
$ bin/rails generate
Usage:
bin/rails generate GENERATOR [args] [options]
...
...
Please choose a generator below.
Rails:
assets
channel
controller
generator
...
...
Можно установить больше генераторов с помощью гемов генераторов, части плагинов, которые вы, несомненно, установите, и даже можете создать свой собственный!
Использование генераторов поможет сэкономить много времени, написав за вас шаблонный код - необходимый для работы приложения.
Давайте создадим свой собственный контроллер с помощью генератора контроллера. Какую же команду использовать? Давайте спросим у генератора:
Все консольные утилиты Rails имеют текст помощи. Как и с большинством утилит *nix, можно попробовать --help
или -h
в конце, например bin/rails server --help
.
$ bin/rails generate controller
Usage:
bin/rails generate controller NAME [action action] [options]
...
...
Description:
...
To create a controller within a module, specify the controller name as a
path like 'parent_module/controller_name'.
...
Example:
`bin/rails generate controller CreditCards open debit credit close`
Credit card controller with URLs like /credit_cards/debit.
Controller: app/controllers/credit_cards_controller.rb
Test: test/controllers/credit_cards_controller_test.rb
Views: app/views/credit_cards/debit.html.erb [...]
Helper: app/helpers/credit_cards_helper.rb
Генератор контроллера ожидает параметры в форме generate controller ControllerName action1 action2
. Давайте создадим контроллер Greetings
с экшном hello, который скажет нам что-нибудь приятное.
$ bin/rails generate controller Greetings hello
create app/controllers/greetings_controller.rb
route get 'greetings/hello'
invoke erb
create app/views/greetings
create app/views/greetings/hello.html.erb
invoke test_unit
create test/controllers/greetings_controller_test.rb
invoke helper
create app/helpers/greetings_helper.rb
invoke test_unit
Что это сгенерировало? Создался ряд директорий в нашем приложении, и создались файл контроллера, файл вью, файл функционального теста, хелпер для вью, файл JavaScript и файл таблицы стилей.
Давайте проверим контроллер и немного его модифицируем (в app/controllers/greetings_controller.rb
):
class GreetingsController < ApplicationController
def hello
@message = "Hello, how are you today?"
end
end
Затем вью для отображения нашего сообщения (в app/views/greetings/hello.html.erb
):
<h1>A Greeting for You!</h1>
<p><%= @message %></p>
Запустим сервер с помощью bin/rails server
.
$ bin/rails server
=> Booting Puma...
URL должен быть http://localhost:3000/greetings/hello.
В нормальном старом добром приложении Rails, ваши URL будут создаваться по образцу http://(host)/(controller)/(action), и URL, подобный такому http://(host)/(controller), вызовет экшн index этого контроллера.
В Rails также есть генератор для моделей данных.
$ bin/rails generate model
Usage:
bin/rails generate model NAME [field[:type][:index] field[:type][:index]] [options]
...
ActiveRecord options:
[--migration], [--no-migration] # Indicates when to generate migration
# Default: true
...
Description:
Generates a new model. Pass the model name, either CamelCased or
under_scored, and an optional list of attribute pairs as arguments.
...
Список доступных типов полей для параметра type
можно узнать в документации API для метода add_column модуля SchemaStatements
. Параметр index
генерирует соответствующий индекс для столбца.
Но вместо генерации модели непосредственно (что мы сделаем еще позже), давайте создадим каркас (scaffold). Скаффолд в Rails - это полный набор из модели, миграции базы данных для этой модели, контроллер для воздействия на нее, вью для просмотра и обращения с данными и тестовый набор для всего этого.
Давайте настроим простой ресурс, названный "HighScore", который будет отслеживать наши лучшие результаты в видеоиграх, в которые мы играли.
$ bin/rails generate scaffold HighScore game:string score:integer
invoke active_record
create db/migrate/20190416145729_create_high_scores.rb
create app/models/high_score.rb
invoke test_unit
create test/models/high_score_test.rb
create test/fixtures/high_scores.yml
invoke resource_route
route resources :high_scores
invoke scaffold_controller
create app/controllers/high_scores_controller.rb
create test/system/high_scores_test.rb
invoke erb
create app/views/high_scores
create app/views/high_scores/index.html.erb
create app/views/high_scores/edit.html.erb
create app/views/high_scores/show.html.erb
create app/views/high_scores/new.html.erb
create app/views/high_scores/_form.html.erb
invoke test_unit
create test/controllers/high_scores_controller_test.rb
invoke helper
create app/helpers/high_scores_helper.rb
invoke test_unit
invoke jbuilder
create app/views/high_scores/index.json.jbuilder
create app/views/high_scores/show.json.jbuilder
create app/views/high_scores/_high_score.json.jbuilder
Генератор создал модель, вью, контроллер, ресурсный маршрут и миграцию базы данных (создающую таблицу high_scores
) для HighScore. Он также добавил тесты для них.
Миграция требует, чтобы мы мигрировали ее, то есть запустили некоторый код Ruby (файл 20190416145729_create_high_scores.rb
из вышеприведенного вывода), чтобы модифицировать схему базы данных. Какой базы данных? Базы данных SQLite3, которую создаст Rails, когда мы запустим команду bin/rails db:migrate
. Поговорим об этой команде ниже.
$ bin/rails db:migrate
== CreateHighScores: migrating ===============================================
-- create_table(:high_scores)
-> 0.0017s
== CreateHighScores: migrated (0.0019s) ======================================
Давайте поговорим о юнит-тестах. Юнит-тесты - это код, который тестирует и делает утверждения о коде. В юнит-тестировании мы берем часть кода, скажем, метод модели, и тестируем его входы и выходы. Юнит-тесты ваши друзья. Чем раньше вы смиритесь с фактом, что качество жизни возрастет, когда станете тестировать свой код с помощью юнит-тестов, тем лучше. Серьезно. Посетите руководство Тестирование приложений на Rails для более глубокого изучения юнит-тестирования.
Давайте взглянем на интерфейс, который Rails создал для нас.
$ bin/rails server
Перейдите в браузер и откройте http://localhost:3000/high_scores, теперь мы можем создать новый рекорд (55,160 в Space Invaders!)
bin/rails console
Команда console
позволяет взаимодействовать с приложением на Rails из командной строки. В своей основе bin/rails console
использует IRB, поэтому, если вы когда-либо его использовали, то будете чувствовать себя уютно. Это полезно для тестирования быстрых идей с кодом и правки данных на сервере не трогая веб-сайт.
Для вызова консоли также можно использовать псевдоним "c": bin/rails c
.
Можно указать среду, в которой должна работать команда console
.
$ bin/rails console -e staging
Если нужно протестировать некоторый код без изменения каких-либо данных, можно это сделать, вызвав bin/rails console --sandbox
.
$ bin/rails console --sandbox
Loading development environment in sandbox (Rails 8.0.0)
Any modifications you make will be rolled back on exit
irb(main):001:0>
app
и helper
Внутри bin/rails console
имеется доступ к экземплярам app
и helper
.
С помощью метода app
доступны хелперы именованных маршрутов, а также можно делать запросы.
irb> app.root_path
=> "/"
irb> app.get _
Started GET "/" for 127.0.0.1 at 2014-06-19 10:41:57 -0300
...
С помощью метода helper
возможно получить доступ к хелперам Rails и вашего приложения.
irb> helper.time_ago_in_words 30.days.ago
=> "about 1 month"
irb> helper.my_custom_helper
=> "my custom helper"
bin/rails dbconsole
bin/rails dbconsole
определяет, какая база данных используется, и перемещает вас в такой интерфейс командной строки, в котором можно ее использовать (и также определяет параметры командной строки, которые нужно передать!). Она поддерживает MySQL (включая MariaDB), PostgreSQL и SQLite3.
Для вызова консоли базы данных также можно использовать псевдоним "db": bin/rails db
.
При использовании нескольких баз данных, bin/rails dbconsole
по умолчанию соединит с основной базой данных. Можно указать, с какой базой данных соединить, с помощью --database
или --db
:
$ bin/rails dbconsole --database=animals
bin/rails runner
runner
запускает код Ruby в контексте неинтерактивности Rails, без необходимости открывать Rails console
. Для примера:
$ bin/rails runner "Model.long_running_method"
Можно также использовать псевдоним "r" для вызова runner: bin/rails r
.
Можно определить среду, в которой будет работать команда runner
, используя переключатель -e
:
$ bin/rails runner -e staging "Model.long_running_method"
С помощью runner даже можно выполнять код ruby, написанный в файле.
$ bin/rails runner lib/code_to_be_run.rb
bin/rails destroy
Воспринимайте destroy
как противоположность generate
. Она выясняет, что было сгенерировано, и отменяет это.
Также можно использовать псевдоним "d" для вызова команды destroy: bin/rails d
.
$ bin/rails generate model Oops
invoke active_record
create db/migrate/20120528062523_create_oops.rb
create app/models/oops.rb
invoke test_unit
create test/models/oops_test.rb
create test/fixtures/oops.yml
$ bin/rails destroy model Oops
invoke active_record
remove db/migrate/20120528062523_create_oops.rb
remove app/models/oops.rb
invoke test_unit
remove test/models/oops_test.rb
remove test/fixtures/oops.yml
bin/rails about
bin/rails about
предоставляет информацию о номерах версий Ruby, RubyGems, Rails, подкомпонентов Rails, папке вашего приложения, имени текущей среды Rails, адаптере базы данных вашего приложения и версии схемы. Это полезно, когда нужно попросить помощь, проверить патч безопасности, который может повлиять на вас, или просто хотите узнать статистику о текущей инсталляции Rails.
$ rails about
About your application's environment
Rails version 8.0.0
Ruby version 3.1.0 (x86_64-linux)
RubyGems version 3.3.7
Rack version 3.0.8
JavaScript Runtime Node.js (V8)
Middleware: ActionDispatch::HostAuthorization, Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, ActionDispatch::ServerTiming, ActiveSupport::Cache::Strategy::LocalCache::Middleware, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, ActionDispatch::RemoteIp, Sprockets::Rails::QuietAssets, Rails::Rack::Logger, ActionDispatch::ShowExceptions, WebConsole::Middleware, ActionDispatch::DebugExceptions, ActionDispatch::ActionableExceptions, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ContentSecurityPolicy::Middleware, ActionDispatch::PermissionsPolicy::Middleware, Rack::Head, Rack::ConditionalGet, Rack::ETag, Rack::TempfileReaper
Application root /home/foobar/my_app
Environment development
Database adapter sqlite3
Database schema version 20180205173523
bin/rails assets:
Можно предварительно компилировать ассеты в app/assets
, используя bin/rails assets:precompile
, и удалять эти скомпилированные ассеты, используя bin/rails assets:clean
. Команда assets:clean
позволяет откатывать деплои, которые все еще могут быть связаны со старыми ассетами, в то время как создаются новые ассеты.
Если хотите полностью очистить public/assets
, можно использовать bin/rails assets:clobber
.
bin/rails db:
Самыми распространенными командами пространства имен rails db:
являются migrate
и create
, но следует попробовать и остальные миграционные команды rails (up
, down
, redo
, reset
). Команда bin/rails db:version
полезна для решения проблем, показывая текущую версию базы данных.
Более подробно о миграциях написано в руководстве Миграции Active Record.
bin/rails notes
bin/rails notes
ищет в вашем коде комментарии, начинающиеся с определенного ключевого слова. Обратитесь к bin/rails notes --help
за подробностями об использовании.
По умолчанию она будет искать в директориях app
, config
, db
, lib
и test
аннотации FIXME, OPTIMIZE и TODO в файлах с расширениями .builder
, .rb
, .rake
, .yml
, .yaml
, .ruby
, .css
, .js
и .erb
.
$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] any other way to do this?
* [132] [FIXME] high priority for next deploy
lib/school.rb:
* [ 13] [OPTIMIZE] refactor this code to make it faster
* [ 17] [FIXME]
Можно указать определенные аннотации с помощью аргумента --annotations
. По умолчанию, она будет искать FIXME, OPTIMIZE и TODO. Отметьте, что аннотации являются чувствительными к регистру.
$ bin/rails notes --annotations FIXME RELEASE
app/controllers/admin/users_controller.rb:
* [101] [RELEASE] We need to look at this before next release
* [132] [FIXME] high priority for next deploy
lib/school.rb:
* [ 17] [FIXME]
Можно добавить больше тегов для поиска по умолчанию, используя config.annotations.register_tags
. Он получает список тегов.
config.annotations.register_tags("DEPRECATEME", "TESTME")
$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] do A/B testing on this
* [ 42] [TESTME] this needs more functional tests
* [132] [DEPRECATEME] ensure this method is deprecated in next release
Можно добавить больше директорий по умолчанию для поиска с помощью config.annotations.register_directories
. Она получает список имен директорий.
config.annotations.register_directories("spec", "vendor")
$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] any other way to do this?
* [132] [FIXME] high priority for next deploy
lib/school.rb:
* [ 13] [OPTIMIZE] Refactor this code to make it faster
* [ 17] [FIXME]
spec/models/user_spec.rb:
* [122] [TODO] Verify the user that has a subscription works
vendor/tools.rb:
* [ 56] [TODO] Get rid of this dependency
Можно добавить больше расширений файлов по умолчанию с помощью config.annotations.register_extensions
. Она получает список расширений с соответствующими регулярными выражениями для сопоставления.
config.annotations.register_extensions("scss", "sass") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ }
+$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] any other way to do this?
* [132] [FIXME] high priority for next deploy
app/assets/stylesheets/application.css.sass:
* [ 34] [TODO] Use pseudo element for this class
app/assets/stylesheets/application.css.scss:
* [ 1] [TODO] Split into multiple components
lib/school.rb:
* [ 13] [OPTIMIZE] Refactor this code to make it faster
* [ 17] [FIXME]
spec/models/user_spec.rb:
* [122] [TODO] Verify the user that has a subscription works
vendor/tools.rb:
* [ 56] [TODO] Get rid of this dependency
bin/rails routes
bin/rails routes
отобразит список всех определенных маршрутов, что полезно для отслеживания проблем с роутингом в вашем приложении, или предоставления хорошего обзора URL приложения, с которым вы пытаетесь ознакомиться.
bin/rails test
Хорошее описание юнит-тестирования в Rails дано в руководстве Тестирование приложений на Rails.
Rails поставляется с тестовым фреймворком под названием minitest. Rails сохраняет стабильность в связи с использованием тестов. Команды, доступные в пространстве имен test:
, помогают с запуском различных тестов, которые вы, несомненно, напишите.
bin/rails tmp:
Директория Rails.root/tmp
является, как любая *nix директория /tmp, местом для временных файлов, таких как файлы id процессов и кэшированные экшны.
Команды пространства имен tmp:
помогут очистить и создать директорию Rails.root/tmp
:
bin/rails tmp:cache:clear
очистит tmp/cache
.
bin/rails tmp:sockets:clear
очистит tmp/sockets
.
bin/rails tmp:screenshots:clear
очистит tmp/screenshots
.
bin/rails tmp:clear
очистит все файлы кэша, сокетов и скриншотов.
bin/rails tmp:create
создает временные директории для кэша, сокетов и идентификаторов процесса (pid).
bin/rails initializers
выведет все определенные инициализаторы в порядке вызова Rails.
bin/rails middleware
выведет стек промежуточных программ Rack, включенных в вашем приложении.
bin/rails stats
великолепно для обзора статистики вашего кода, отображает такие вещи, как KLOCs (тысячи строчек кода) и ваш код для тестирования показателей.
bin/rails secret
даст псевдо-случайный ключ для использования в качестве секретного ключа сессии.
bin/rails time:zones:all
перечислит все временные зоны, о которых знает Rails.
Пользовательские задачи rake имеют расширение .rake
и располагаются в Rails.root/lib/tasks
. Эти пользовательские задачи rake можно создать с помощью команды bin/rails generate task
.
desc "I am short, but comprehensive description for my cool task"
task task_name: [:prerequisite_task, :another_task_we_depend_on] do
# Вся магия тут
# Разрешен любой код Ruby
end
Чтобы передать аргументы в ваш задачу rake:
task :task_name, [:arg_1] => [:prerequisite_1, :prerequisite_2] do |task, args|
argument_1 = args.arg_1
end
Задачи можно группировать, помещая их в пространства имен:
namespace :db do
desc "This task does nothing"
task :nothing do
# Серьезно, ничего
end
end
Вызов задач выглядит так:
$ bin/rails task_name
$ bin/rails "task_name[value 1]" # весь аргумент в виде строки должен быть в кавычках
$ bin/rails "task_name[value 1,value2,value3]" # несколько аргументов, разделенных запятой
$ bin/rails db:nothing
Если необходимо взаимодействовать с моделями приложения, выполнять запросы в базу данных и так далее, ваша задача должна зависеть от задачи environment
, которая загрузит код вашего приложения.
task task_that_requires_app_code: [:environment] do
User.create!
end