Создаем первое приложение в Ruby on Rails 3
В этой статье я хочу рассказать, как создать простое приложение, работающее с базой данных MySQL в среде Ruby on Rails 3. Можно рассматривать этот материал, как пошаговое руководство для начинающих программистов Rails.
Итак, для работы нам необходима установленные рельсы и rubygems. С последними у меня вчера была проблема, поэтому пришлось удалить пакет rubygems1.8 не понятно как оказавшийся в системе и поставить rubygems1.9 Напомню, что разрабатываю я на Ubuntu, хотя для Windows команды консоли Rails думаю будут теми же. В качестве среды разработки использую NetBeans с плагином для Ruby on Rails. Про установку неплохо написано в этой статье моего коллеги.
Проверка ссылок
Необходимо убедиться, что каталог /usr/bin содержит символические ссылки rails, rake, ruby, bundler на файлы из каталога /usr/local/ruby/bin. Дл просмотра ссылок используйте команду:
ls -l | grep rails
или
ls -l | grep rake
в зависимости от того, что хотите отфильтровать.
Создаем приложение
Я создал специальный каталог для своих ruby-приложений.
mkdir /home/andrey/ruby
cd /home.andrey/ruby
У рельсов есть много консольных утилит, которые сильно облегчают работу, в особенности по прототипированию. Для создания приложения, использующего в качестве базы mysql выполним команду:
rails new app -d mysql
app – это название нашего нового приложения. После выполнения команды мы увидим, как rails сделал нам каркас будущего приложения.
root@vaio:~/ruby# rails new app -d mysql
create
create README
create Rakefile
create config.ru
create .gitignore
create Gemfile
create app
create app/controllers/application_controller.rb
create app/helpers/application_helper.rb
create app/mailers
create app/models
create app/views/layouts/application.html.erb
create config
create config/routes.rb
create config/application.rb
create config/environment.rb
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
create config/initializers
create config/initializers/backtrace_silencers.rb
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/initializers/secret_token.rb
create config/initializers/session_store.rb
create config/locales
create config/locales/en.yml
create config/boot.rb
create config/database.yml
create db
create db/seeds.rb
create doc
create doc/README_FOR_APP
create lib
create lib/tasks
create lib/tasks/.gitkeep
create log
create log/server.log
create log/production.log
create log/development.log
create log/test.log
create public
create public/404.html
create public/422.html
create public/500.html
create public/favicon.ico
create public/index.html
create public/robots.txt
create public/images
create public/images/rails.png
create public/stylesheets
create public/stylesheets/.gitkeep
create public/javascripts
create public/javascripts/application.js
create public/javascripts/controls.js
create public/javascripts/dragdrop.js
create public/javascripts/effects.js
create public/javascripts/prototype.js
create public/javascripts/rails.js
create script
create script/rails
create test
create test/fixtures
create test/functional
create test/integration
create test/performance/browsing_test.rb
create test/test_helper.rb
create test/unit
create tmp
create tmp/sessions
create tmp/sockets
create tmp/cache
create tmp/pids
create vendor/plugins
create vendor/plugins/.gitkeep
Заходим в папку с ним и устанавливаем необходимые гемы. Гемы – это подключаемые библиотеки, необходимые для проекта (аналог PHP’шных PECL и PEAR).
cd ./app
bundle install
После этого, в консоли будет что-то вроде этого:
andrey@vaio:~/ruby/app> sudo bundle install
Using rake (0.8.7)
Using abstract (1.0.0)
Using activesupport (3.0.0)
Using builder (2.1.2)
Using i18n (0.4.2)
Using activemodel (3.0.0)
Using erubis (2.6.6)
Using rack (1.2.1)
Using rack-mount (0.6.13)
Using rack-test (0.5.6)
Using tzinfo (0.3.23)
Using actionpack (3.0.0)
Using mime-types (1.16)
Using polyglot (0.3.1)
Using treetop (1.4.8)
Using mail (2.2.9)
Using actionmailer (3.0.0)
Using arel (1.0.1)
Using activerecord (3.0.0)
Using activeresource (3.0.0)
Using bundler (1.0.3)
Using mysql2 (0.2.6)
Using thor (0.14.4)
Using railties (3.0.0)
Using rails (3.0.0)
Your bundle is complete! Usebundle show [gemname]
to see where a bundled gem is installed.
Это значит, что все гемы установлены и подключены. Если чего-то не хватает, то bundle сам скачает их с rubygems и установит. Вот этого мне долгое время не хватало в php, по сути получается установщик проекта. Список зависимых гемов находится в файле Gemfile в корне проекта.
Конфигурирование
Теперь надо укаать реквизиты доступа к БД нашего проекта. Открываем проект в NetBeans: New Project -> Ruby -> Ruby on Rails application with existing source. Указываем путь, в моем случае это будет (/home/andrey/ruby/app) и название проекта(app). В качестве Ruby Platform выбираем установленную в системе, а не встроенную в NetBeans. Нажимаем Finish и проект создался. Открываем псевдо-папку Configuration и файл database.yml. Здесь надо указать логин и пароль для доступа к базе, желательно сразу для всех трех окружений (development, test, production). Окружение – это среда в которой будет запускаться наше приложение,
- development – компьютер разработчика,
- production – сервер промышленной эксплуатации,
- test – работа в режиме тестирования на сервере непрерывной интеграции или компьютере тестировщика.
Пароль пишем в кавычках. Дальше необходимо создать модель данных, например создадим модель пользователя. Делаем это из консоли в папке проекта:
rails generate model User name:string hashed_password:string salt:string
Сразу видно, чего нагенерил нам Rails:
invoke active_record
create db/migrate/20101107054200_create_users.rb
create app/models/user.rb
invoke test_unit
create test/unit/user_test.rb
create test/fixtures/users.yml
Отлично, теперь нам надо создать базу данных. Выполняем для этого:
andrey@vaio:~/ruby/app$ rake db:create
(in /home/andrey/ruby/app)
andrey@vaio:~/ruby/app$ rake db:migrate
(in /home/andrey/ruby/app)
== CreateUsers: migrating ====================================================
— create_table(:users)
-> 0.0061s
== CreateUsers: migrated (0.0063s) ===========================================
Консоль выводит добавленные данные. Смотрим в phpmyadmin и видим новые базы app_development и app_test, а также таблицы в них. Теперь настала очередь добавить реальные данные. Для этого запускаем консоль rails
rails console
Консоль – это не просто консоль, а консоль IRB в контексте вашего приложения. В качестве примера создадим двух пользователей:
andrey@vaio:~/ruby/app$ rails console
Loading development environment (Rails 3.0.0)
irb(main):001:0> user1 = User.new
=> #<User id: nil, name: nil, hashed_password: nil, salt: nil, created_at: nil, updated_at: nil>
irb(main):002:0> user1.name = “andrey”
=> “andrey”
irb(main):003:0> user1.save
=> true
irb(main):004:0> user2 = User.new
=> #<User id: nil, name: nil, hashed_password: nil, salt: nil, created_at: nil, updated_at: nil>
irb(main):005:0> user2.name = “vasiliy”
=> “vasiliy”
irb(main):006:0> user2.save
=> trueirb(main):007:0> exit
andrey@vaio:~/ruby/app$
Посмотрим в базу, и действительно у нас появились два пользователя. Хочется отметить, что Rails сам добавил столбцы первичного ключа и поля created_at (дата создания) и updated_at (дата изменения) модели.
Модель у нас есть, данные тоже. Пора запустить наше приложение.
andrey@vaio:~/ruby/app$ rails server
=> Booting WEBrick
=> Rails 3.0.0 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-11-07 10:59:22] INFO WEBrick 1.3.1
[2010-11-07 10:59:22] INFO ruby 1.9.2 (2010-08-18) [x86_64-linux]
[2010-11-07 10:59:22] INFO WEBrick::HTTPServer#start: pid=4193 port=3000
Приложение запущено, открываем броузер по адресу http://localhost:3000/ и видим тестовую страничку.
Отлично, приложение работает. Но оно показывает обычную HTML-страничку из папки /public/index.html. А мы хотим динамическую. Открываем второе окно консоли (т.к. в первом у нас запущен вер-сервер руби – WebRick), заходим в папку с проектом и набираем там следующую команду:
andrey@vaio:~/ruby/app$ rails generate controller index index
create app/controllers/index_controller.rb
route get “index/index”
invoke erb
create app/views/index
create app/views/index/index.html.erb
invoke test_unit
create test/functional/index_controller_test.rb
invoke helper
create app/helpers/index_helper.rb
invoke test_unit
create test/unit/helpers/index_helper_test.rb
andrey@vaio:~/ruby/app$
Этим мы создали коонтроллер Index, в нём действие Index и вид этого действия index.html.erb Делаем Refresh(F5) в NetBeans и смотрим наши файлы. Замечательно. Теперь нам надо как-то перенаправить маршрут для главной страницы на созданное нам действие контроллера. Открываем файл маршрутов (Configuration/routes.rb) и раскомментируем там следующую строчку:
# You can have the root of your site routed with “root”
# just remember to delete public/index.html.
root :to => “welcome#index”
Только вместо welcome пишем тоже index. Ну привык я по Zend Framework’у, что контроллер и действие по-умолчанию называются index 🙂 Не забыавем удалить (или переименовать) файл public/index.html).
root :to => “index#index”
Обновляем страничку в броузере, и видим, что теперь отображается наш вид.
Index#index
Find me in app/views/index/index.html.erb
Отлично. Теперь можно кодить 🙂 Заходим в наш вновь созданный контроллер (Controllers -> index_controller.rb) и пишем там такой текст действия:
class IndexController < ApplicationController
def index
@users = User.find(:all)
end
end
Тепеь открываем вид Views/index/index.html.erb и пишем там такой код:
<h1>Index#index</h1>
<p>Find me in app/views/index/index.html.erb</p>
<% for user in @users -%>
<i><%=user.name%></i><br/>
<% end %>
Этим, мы говорим Rails пройтись по массиву пользователей и отобразить их имена. Обновляем страничку и видим список пользователей внизу.
Index#index
Find me in app/views/index/index.html.erb
andrey
vasiliy
Отлично! Приложение создано!
Дружище, ты написал нереально втыкаемый пост.
Эм, так он всё-таки втыкаемый или не втыкаемый?)
UPD: Судя по Like в баззе всё-таки втыкаемый 🙂
Втыкаемый, спасибо. Уже ищу что-нибудь про scaffold.
а как мультисайтовость в руби или refinary CMS сделать? Или такое невозможно?
Возможно конечно. Но я подобное на Ruby не делал.
Спасибо большое за статью!
Очень класcный пост, спасибо!