Статьи

От нуля до шестидесяти: создание и развертывание приложения Rails менее чем за час

Дважды в месяц мы возвращаемся к любимым постам наших читателей на протяжении всей истории Nettuts +. Этот учебник был впервые опубликован в январе 2010 года.

Дайте мне час вашего времени, и я поймаю вас на лету из среды Ruby on Rails. Мы создадим контроллеры, модели, представления, добавим логины администратора и развернем их с помощью сервиса Heroku менее чем за час! В этой статье мы создадим простое приложение для книжных полок, в которое вы сможете добавлять книги и писать мысли о них. Затем мы развернем приложение всего за несколько минут. Так что пристегнитесь, потому что эта статья движется быстро!

В этой статье предполагается, что вы можете знать, что такое Ruby on Rails, но не совсем точно, как он работает. Эта статья не описывает подробно, как работает каждый шаг, но она описывает, что нам нужно сделать, а затем код для этого.


Ruby on Rails представляет собой полнофункциональную инфраструктуру веб-приложений MVC. Полный стек означает, что вы получаете все: простой веб-сервер, который вы можете использовать для тестирования своих приложений, уровень базы данных, среду тестирования и дизайн на основе MVC. MVC расшифровывается как Model-View-Controller.

Модель хранит информацию. Модели хранятся в базе данных. Rails поддерживает MySQL, PostgreSQL или SQLite. Каждая модель имеет свой класс и таблицу. Скажем, мы хотим смоделировать «игру». В игре есть такие вещи, как количество игроков, время начала, время окончания, игра команд и победитель. Эти атрибуты становятся столбцами в таблице «игры». Имена таблиц строчные, подчеркнутые и множественные. Название класса модели — Game. В Rails вы создаете модели с помощью миграций и генераторов. Миграция описывает, как добавить / удалить столбцы и таблицы из базы данных.

Контроллер — это менеджер. Он берет информацию и выполняет некоторую логику, такую ​​как CRUD, или, возможно, импортирует некоторые вещи из файла, добавляет / удаляет разрешения — вы называете это контроллером, который может это делать. Контроллеры — это часть вашего приложения . Как мы называем контроллеры? Rails использует маршруты. Маршрут — это отформатированный URL-адрес, связанный с действием с набором параметров. Возвращаясь к модели Game, нам нужен контроллер для функциональности. В какой-то момент нам нужно будет перечислить все игры в системе. Основной REST-URL для этого маршрута выглядит как «/ games». Как Rails узнает, какой контроллер искать и какое действие вызывать? Он смотрит на ваш файл rout.rb. У вас может быть маршрут, который выглядит так: «GET / make {: name => ‘games’,: action => ‘index'»}. Это переводит в GamesController и его метод индекса. Как и модели, имена классов — CamelCase, а имена файлов подчеркнуты. Таким образом, наш GamesController будет храниться в /app/controllers/games_controller.rb. После логики контроллер отображает представление.

Вид — это самая простая часть для понимания. Это то, что ты видишь. Это HTML, который вы генерируете, чтобы показать пользователю, что ему нужно. Представления являются шаблонами ERB. ERB расшифровывается как Embedded Ruby. Вы используете ERB аналогично тому, как вы вставляете php в документ. Если вы хотите вставить переменную экземпляра @ game.time в html, напишите <% = @ game.time%>


Сначала установите Rails. Установка Rails очень проста в зависимости от вашей платформы. Если вы используете Linux / OSX, это не проблема. Windows более сложная, и у меня нет опыта работы с ней. Этот раздел даст вам краткий обзор установки Rails через RubyGems, менеджер пакетов Ruby. Драгоценный камень — это пакет кода ruby ​​в пакете, который можно использовать в ваших программах. Для системы на основе UNIX установите RubyGems, затем установите гем Rails. Этот процесс будет выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
# ubuntu
sudo apt-get install rubygems
# fedora
sudo yum install rubygems
# gentoo
sudo emerge rubygems
# OSX
sudo port install rubygems
 
# after you have rubygems installed
sudo gem install gemcutter # ruby gem hosting service
sudo gem tumble
sudo gem install Rails

Вот несколько ссылок, которые помогут вам в процессе установки

Как только вы сможете запустить команду «rails», вы готовы к следующему шагу.


Теперь пришло время установить поддержку базы данных, прежде чем мы начнем. Rails поддерживает все популярные БД, но в этом примере мы будем использовать SQLite, потому что он легкий. В зависимости от вашей платформы (опять же) установка поддержки sqlite может быть простой или болезненной. Это может быть проблемой, так как гем должен быть построен на основе расширений C, что означает, что пакет sqlite3 должен быть установлен в вашей системе. Опять процесс пойдет примерно так:

1
2
3
4
5
6
7
8
9
# ubuntu
sudo apt-get install sqlite3 sqlite3-devel
# fedora
sudo yum install sqlite3 sqlite3-devel
# OSX
sudo port install sqlite3
 
# then once you have the sqlite3 package installed
sudo gem install sqlite3-ruby

Прочитайте предыдущие ссылки, если у вас возникли проблемы с этими шагами. Они также описывают установку sqlite.


Время создавать наше приложение. Команда rails создает базовую структуру приложения. Все, что нам нужно сделать, это быть в каталоге и запустить его так:

1
2
3
$ cd ~/projects
$ Rails bookshelf #this will create a new directory named bookshelf that holds our app
$ cd bookshelf

Важно отметить, что по умолчанию Rails является приложением на основе SQLite. Вы можете подумать, а что если я не хочу этого? Команда rails является генератором. Все, что он делает, это копирует сохраненные файлы в новый каталог. По умолчанию он создает базы данных sqlite3 в /bookshelf/db/development.sqlite3, /bookshelf/db/production.sqlite3 и /bookshelf/db/testing.sqlite3. Информация о соединении с базой данных хранится в /bookshelf/config/database.yml. Вам не нужно редактировать этот файл, так как он содержит информацию по умолчанию для установки sqlite. Это должно выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
# SQLite version 3.x
# gem install sqlite3-ruby (not necessary on OS X Leopard)
development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000
 
# Warning: The database defined as «test» will be erased and
# re-generated from your development database when you run «rake».
# Do not set this db to the same as development or production.
test:
  adapter: sqlite3
  database: db/test.sqlite3
  pool: 5
  timeout: 5000
 
production:
  adapter: sqlite3
  database: db/production.sqlite3
  pool: 5
  timeout: 5000

Обратите внимание, что назначены разные среды. В Rails есть три режима: разработка, тестирование и производство. У каждого свои настройки и базы данных. Разработка является средой по умолчанию. На данный момент мы можем запустить наше приложение, чтобы убедиться, что оно работает. Вы можете видеть, что есть каталог с именем / script. Этот каталог содержит рубиновые скрипты для взаимодействия с нашим приложением. Некоторые важные из них: / script / console и / script / server. Мы будем использовать команду / script / server, чтобы запустить простой сервер для нашего приложения.

1
2
3
4
5
6
bookshelf $ ./script/server
# then you should see something like this.
=> Booting Mongrel
=> Rails 2.3.5 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server

Время посетить приложение. Укажите в браузере «http: // localhost: 3000», и вы должны увидеть эту заставку:

Заставка

Ты едешь на Рельсах. Теперь, когда код работает на базовом уровне, пришло время удалить заставку и приступить к работе с некоторым кодом.

1
bookshelf $ rm /public/index.html

Наше приложение нуждается в данных. Помните, что это значит? Это значит модели . Отлично, но как мы генерируем модель? Rails поставляется с некоторыми генераторами для общих задач. Генератором является файл / скрипт / сгенерировать. Генератор создаст наш файл model.rb вместе с миграцией, чтобы добавить таблицу в базу данных. Файл миграции содержит код для добавления / удаления таблиц или изменения / добавления / удаления столбцов из таблиц. Миграции выполняются последовательно для создания таблиц. Запустите миграцию (и другие команды) с помощью «rake». Рейк — это бегун по рубиновому коду. Прежде чем мы продолжим, давайте начнем с определения некоторой базовой информации для книг. Книга имеет следующие атрибуты:

  • Название: Строка
  • Мысли: текст

Этого достаточно, чтобы запустить приложение. Начните с создания модели с этими полями, используя генератор моделей:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
bookshelf $ ./script/generate model Book title:string thoughts:text
# notice how the attributes/types are passed to the generator.
# These are optional.
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/book.rb
create test/unit/book_test.rb
create test/fixtures/books.yml
create db/migrate
create db/migrate/20091202052507_create_books.rb
# The generator created all the files we need to get our model up and running.
# app/models/book.rb # where our code resides
# db/migrate/20091202052507_create_books.rb # code to create our books table.

Откройте файл миграции:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
class CreateBooks < ActiveRecord::Migration
  def self.up
    create_table :books do |t|
      t.string :title
      t.text :thoughts
 
      t.timestamps
    end
  end
 
  def self.down
    drop_table :books
  end
end

Обратите внимание на блок create_table: books. Здесь создаются столбцы. Первичный ключ id создается автоматически. t.timestamps добавляет столбцы для созданных и обновленных. Теперь запустите миграцию, используя задачу rake db: migrate. db: migrate применяет отложенные миграции:

1
2
3
4
5
bookshelf $ rake db:migrate
== CreateBooks: migrating ====================================================
— create_table(:books)
   -> 0.0037s
== CreateBooks: migrated (0.0038s) ===========================================

Круто, теперь у нас есть таблица, давайте создадим пустышку только для ударов в консоли. Консоль Rails использует IRB (интерактивный ruby) и загружает все классы для вашего проекта. То есть вы можете получить доступ ко всем вашим моделям. Откройте консоль так:

1
2
3
4
5
6
7
8
9
bookshelf $ ./script/console
>> # let’s create a new model.
>> book = Book.new :title => ‘Rails is awesome!’
=> #<Book id: nil, title: «Rails is awesome!», thoughts: «Some sentence from a super long paragraph», created_at: nil, updated_at: nil> # and ruby will display it back
>> book.save
=> true # now are book is saved in the database.
>> Book.all # find all books and return them in an array
=> [#<Book id: 1, title: «Rails is awesome!», thoughts: «Some sentence from a super long paragraph», created_at: «2009-12-02 06:05:38», updated_at: «2009-12-02 06:05:38»>]
>> exit # now that our model is saved, let’s exit the console.

Теперь, когда мы можем создавать книги, нам нужен способ показать их пользователю


Помните контроллеры? Нам нужен контроллер для отображения всех книг в системе. Этот сценарий соответствует действию index в нашем BooksController (books_controller.rb), которого у нас пока нет. Как и генерация моделей, используйте генератор для создания контроллера:

01
02
03
04
05
06
07
08
09
10
11
bookshelf $ ./script/generate controller Books
exists app/controllers/
exists app/helpers/
create app/views/books
exists test/functional/
create test/unit/helpers/
create app/controllers/books_controller.rb
create test/functional/books_controller_test.rb
create app/helpers/books_helper.rb
create test/unit/helpers/books_helper_test.rb
# notice Rails created the file app/controllers/books_controller.rb?

Нам нужно определить действие, которое находит и отображает все книги. Как мы нашли все книги? Ранее мы использовали Book.all. Наша стратегия — использовать Book.all и назначить его переменной экземпляра. Почему переменная экземпляра? Мы присваиваем переменные экземпляра, потому что представления отображаются с привязкой контроллеров. Вы, наверное, думаете о привязках и переменных экземпляра … что происходит? Представления имеют доступ к переменным, определенным в действиях, но только к переменным экземпляра. Почему, потому что переменные экземпляра ограничены объектом, а не действием. Давайте посмотрим код:

1
2
3
4
5
6
class BooksController < ApplicationController
  # notice we’ve defined a method called index for a BooksController instance.
  def index
    @books = Book.all # instance variables are prefixed with an @.
  end
end

Теперь контроллер может найти все книги. Но как мы можем связать это с URL? Мы должны создать несколько маршрутов. Rails поставляется с некоторыми удобными функциями для генерации RESTful-маршрутов (еще один принцип проектирования Rails). Это сгенерирует URL, такие как / make и / make / 1, в сочетании с глаголами HTTP, чтобы определить, какой метод вызывать в нашем контроллере. Используйте map.resources для создания маршрутов RESTful. Откройте файл /config/routes.rb и измените его следующим образом:

1
2
3
ActionController::Routing::Routes.draw do |map|
  map.resources :books
end

Routes.rb может показаться загадочным для новых пользователей. К счастью, есть способ расшифровать этот беспорядок. Существует задача грабли маршрутов для отображения всей вашей информации о маршрутизации. Запустите это сейчас и загляните внутрь:

01
02
03
04
05
06
07
08
09
10
11
12
bookshelf $ rake routes
    books GET /books(.:format) {:controller=>»books», :action=>»index»}
          POST /books(.:format) {:controller=>»books», :action=>»create»}
 new_book GET /books/new(.:format) {:controller=>»books», :action=>»new»}
edit_book GET /books/:id/edit(.:format) {:controller=>»books», :action=>»edit»}
     book GET /books/:id(.:format) {:controller=>»books», :action=>»show»}
          PUT /books/:id(.:format) {:controller=>»books», :action=>»update»}
          DELETE /books/:id(.:format) {:controller=>»books», :action=>»destroy»}
# as you can see this command can display a lot of information.
# for example GET /books will call BooksController#index or
# GET /books/1 will call BooksController#show
# the url helpers are very important but we’ll get to them later.

Теперь нам нужно создать шаблон для отображения всех наших книг. Создайте новый файл с именем /app/views/books/index.html.erb и вставьте его:

1
2
3
4
<% for book in @books do %>
  <h2><%=h book.title %></h2>
  <p><%= book.thoughts %></p>
<% end %>

Это простое представление перебирает все @books и отображает HTML для каждой книги. Обратите внимание на небольшую разницу. <% = используется, когда нам нужно вывести некоторый текст. <% используется, когда мы нет. Если вы не будете следовать этому правилу, вы получите исключение. Также обратите внимание на h перед book.title. h — это метод, который экранирует сущности HTML. Если вы не знакомы с ruby, вы можете отключить вызовы методов (), если они не нужны. h текст переводится как: h (текст).

Время запустить сервер и посмотреть, что у нас есть. Запустите сервер, затем перейдите по адресу http: // localhost / books.

1
bookshelf $ ./script/server

Если все идет по плану, вы должны увидеть базовый HTML.

книги

У нас есть одна книга в нашей системе, но нам нужно больше книг для игры. Есть несколько способов сделать это. Мне нравится камень подделки. Подделка может создавать случайные строки, такие как имена, или lorem ipsum. Мы собираемся установить зависимость gem в нашем приложении, установить gem, а затем использовать его для создания задачи rake для заполнения наших данных. Шаг 1: откройте /config/environment.rb и добавьте эту строку:

1
config.gem ‘forgery’
1
2
3
4
# now let’s tell Rails to install all gems dependencies for this project
# gem install gemcutter # if you haven’t already
# gem tumble # again, if you haven’t already
bookshelf $ sudo rake gems:install

Теперь мы собираемся использовать классы подделки для создания поддельных данных. Документация по подделке находится здесь . Мы будем использовать LoremIpsumForgery для создания некоторых основных данных. Мы можем определить наши собственные задачи rake, создав файл .rake в / lib / tasks. Поэтому создайте новый файл /lib/tasks/populate.rake:

01
02
03
04
05
06
07
08
09
10
11
12
begin
  namespace :db do
    desc «Populate the development database with some fake data»
    task :populate => :environment do
      5.times do
        Book.create!
      end
    end
  end
rescue LoadError
  puts «Please run: sudo gem install forgery»
end

Это грабли создаст пять поддельных книг. Обратите внимание, я добавил начало / спасение. Когда вы запускаете задачу rake, она просматривает все возможные задачи в инициализации rake. Если бы вы запустили какое-либо задание перед тем, как установить драгоценный камень, рейк взорвался бы. Оборачиваем его в начало / спасательная остановка грабли от прерывания. Запустите задачу, чтобы заполнить нашу базу данных:

1
2
3
4
5
bookshelf $ rake db:populate
bookshelf $ ./script/console # let’s enter the console to verify it all worked
>> Book.all
=> [#<Book id: 1, title: «Rails is awesome!», thoughts: «Some sentence from a super long paragraph», created_at: «2009-12-02 06:05:38», updated_at: «2009-12-02 06:05:38»>, #<Book id: 2, title: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», thoughts: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», created_at: «2009-12-02 07:28:05», updated_at: «2009-12-02 07:28:05»>, #<Book id: 3, title: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», thoughts: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», created_at: «2009-12-02 07:28:05», updated_at: «2009-12-02 07:28:05»>, #<Book id: 4, title: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», thoughts: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», created_at: «2009-12-02 07:28:05», updated_at: «2009-12-02 07:28:05»>, #<Book id: 5, title: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», thoughts: «Lorem ipsum dolor sit amet, consectetuer adipiscing…», created_at: «2009-12-02 07:
>> exit

Запустите сервер снова и вернитесь на страницы / books. Тебе следует увидеть:

Книжный указатель

Теперь у нас есть список из более чем одной книги. Что если у нас много книг? Нам нужно разбить результаты на страницы. Для этого есть еще один драгоценный камень. Драгоценный камень ‘will_paginate.’ Следуя тем же шагам, что и раньше, давайте добавим зависимость gem для ‘will_paginate’ и rake gems: install:

1
2
3
4
5
6
# in environment.rb
config.gem ‘will_paginate’
# from terminal
bookshelf $ sudo rake gems:install
# then let’s add more books to our db
bookshelf $ rake db:populate # run this a few times to get a large sample, or change the number in rake file

Вернитесь на свою страницу / книги, и в этот момент вас должны засыпать книги. Пришло время добавить нумерацию страниц. Пагинация работает на двух уровнях. Контроллер решает, какие книги должны быть в @books, и представление должно отображать ссылки на страницы. Помощник will_paginate делает это очень просто. Мы будем использовать метод .paginate и помощник вида will_paginate для отображения ссылок на страницы. Все это занимает две строки кода.

1
2
3
4
5
# books_controller.rb, change the previous line to:
@books = Books.paginate :page => params[:page], :per_page => 10
 
# index.html.erb, add this line after the loop:
<%= will_paginate @books %>

Вернитесь на свою страницу / делает и вы увидите несколько ссылок на страницы (если у вас более 10 книг)

Страничные книги

Сладкий! Мы движемся через это приложение. Пришло время немного улучшить нашу страницу. Один из ключевых принципов Rails — СУХОЙ (не повторяйте себя). Мы могли бы поработать над выполнением некоторого базового CSS, чтобы страница выглядела нормально, или мы могли бы сделать вещи СУХИМЫМИ и использовать некоторый код, чтобы сделать это для нас. Мы будем использовать гем изящных генераторов Райана Бэйта для создания макета сайта. Макет — это шаблон, который ваши представления могут заполнить. Например, мы можем использовать макет, чтобы определить общую структуру страницы, а затем определить, где представления заполняют ее. Поскольку это не зависимость от проекта, мы не должны добавить его в environment.rb. Мы можем просто установить его регулярно.

1
2
# console
$ sudo gem install nifty-generators

Запустите генератор, чтобы создать файл макета и таблицы стилей.

1
2
3
4
5
6
7
$ ./script/generate nifty_layout
exists app/views/layouts
exists public/stylesheets
exists app/helpers
create app/views/layouts/application.html.erb # this is our layout file
create public/stylesheets/application.css # css file that styles the layout
create app/helpers/layout_helper.rb # view helpers needed in the generator

Взгляните на файл application.html.erb и посмотрите, что внутри:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict//EN»
  «http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>
<html>
  <head>
    <title><%= h(yield(:title) || «Untitled») %></title>
    <%= stylesheet_link_tag ‘application’ %>
    <%= yield(:head) %>
  </head>
  <body>
    <div id=»container»>
      <%- flash.each do |name, msg|
        <%= content_tag :div, msg, :id => «flash_#{name}» %>
      <%- end -%>
 
      <%- if show_title?
        <h1><%=h yield(:title) %></h1>
      <%- end -%>
 
      <%= yield %>
    </div>
  </body>
</html>

Видишь эти урожаи? Вот где представление заполняет макет. У последнего выхода нет аргументов. Контент по умолчанию идет туда. У выходов с аргументом должен быть контент, определенный с помощью content_for. Исправьте представление index.html.erb, чтобы оно соответствовало новому макету:

1
2
3
4
5
6
7
8
<% title ‘My Books’ %>
 
<% for book in @books do %>
  <h2><%=h book.title %></h2>
  <p><%= book.thoughts %></p>
<% end %>
 
<%= will_paginate @books %>

Все, что мы сделали, это добавили метод title, который устанавливает заголовок для страницы. Помощник по заголовку вызывает content_for: title и устанавливает его в качестве аргумента. Наш взгляд заполняет последнюю доходность. Проверьте результаты!

Отличный макет

Теперь, когда наше приложение выглядит лучше, давайте добавим немного взаимодействия. В типичном стиле Web 2.0 мы собираемся позволить пользователям комментировать наш контент, но мы не собираемся требовать от пользователя регистрации. Нам нужно создать новую модель под названием Comment. Комментарий будет иметь некоторый текст, автора и связанную книгу. Как мы связываем эти две модели вместе? Ассоциации. Rails предоставляет следующие ассоциации: assign_to, has_many, has_one и has_and_belongs_to many. Должно быть легко увидеть, что книга имеет много комментариев, и комментарий принадлежит к книге. Поэтому мы будем использовать генератор для создания модели комментариев и миграции:

1
2
3
4
5
6
7
8
9
$ ./script/generate model Comment text:text author:string
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/comment.rb
create test/unit/comment_test.rb
create test/fixtures/comments.yml
exists db/migrate
create db/migrate/20091202081421_create_comments.rb

Внимательные читатели заметят, что в этой миграции отсутствует колонка внешнего ключа. Мы должны добавить это сами. Откройте миграцию create_comments.rb:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
class CreateComments < ActiveRecord::Migration
  def self.up
    create_table :comments do |t|
      t.text :text
      t.string :author
      t.belongs_to :book # creates a new integer column named book_id
      t.timestamps
    end
  end
 
  def self.down
    drop_table :comments
  end
end
1
2
3
4
5
6
7
8
# now migrate your database
$ rake db:migrate
rake db:migrate
(in /Users/adam/Code/bookshelf)
== CreateComments: migrating =================================================
— create_table(:comments)
   -> 0.0021s
== CreateComments: migrated (0.0022s) ========================================

Теперь пришло время связать наши модели, используя ассоциации Rails. Мы будем вызывать метод внутри тела класса модели. Rails использует метапрограммирование для генерации методов, необходимых для работы нашей ассоциации. Мы отредактируем наши файлы comment.rb и book.rb:

1
2
3
4
5
6
7
8
9
# book.rb
class Book < ActiveRecord::Base
  has_many :comments
end
 
# comment.rb
class Comment < ActiveRecord::Base
  belongs_to :book
end

Теперь экземпляры Book имеют метод .comments with, возвращающий массив всех его комментариев. Экземпляры комментариев имеют метод с именем .book, который возвращает связанную книгу. Используйте оператор << для добавления объектов в массивы. Давайте посмотрим, как это работает в консоли:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
$ ./script/console
>> book = Book.find(1)
=> #<Book id: 1, title: «Rails is awesome!», thoughts: «Some sentence from a super long paragraph», created_at: «2009-12-02 06:05:38», updated_at: «2009-12-02 06:05:38»>
>> comment = Comment.new :text => «This is an comment», :author => «Adam»
=> #<Comment id: nil, text: «This is an comment», author: «Adam», book_id: nil, created_at: nil, updated_at: nil>
>> book.comments << comment
=> [#<Comment id: 1, text: «This is an comment», author: «Adam», book_id: 1, created_at: «2009-12-02 08:25:47», updated_at: «2009-12-02 08:25:47»>]
>> book.save
=> true
>> book.comments
=> [#<Comment id: 1, text: «This is an comment», author: «Adam», book_id: 1, created_at: «2009-12-02 08:25:47», updated_at: «2009-12-02 08:25:47»>]
>> comment.book
=> #<Book id: 1, title: «Rails is awesome!», thoughts: «Some sentence from a super long paragraph», created_at: «2009-12-02 06:05:38», updated_at: «2009-12-02 06:05:38»>
>> exit

В сеансе консоли я нашел одну из существующих книг, а затем создал новый комментарий. Затем я добавил его в book.comments. Тогда я сохраняю книгу. Книга должна быть сохранена для сохранения ассоциации. Что дальше? Нам нужно создать страницу, где пользователь сможет просматривать книгу и все ее комментарии. Эта страница также должна иметь форму, где пользователь может добавить свой комментарий. Создайте новое действие в контроллере книг, чтобы показать детали для указанной книги. Книга найдена по id. Зайдите в books_controller.rb и добавьте это:

1
2
3
def show
  @book = Book.find params[:id]
end

Создайте новый шаблон для этого действия в /app/views/books/show.html.erb и вставьте его:

1
2
3
4
<% title @book.title %>
 
<h2><%=link_to(h(@book.title), book_path(@book)) %></h2>
<p><%= @book.thoughts %></p>

Теперь давайте добавим несколько ссылок на действия индекса, чтобы связать действие show:

1
2
3
4
5
6
7
8
9
# update index.html.erb contents to:
<% title ‘My Books’ %>
 
<% for book in @books do %>
  <h2><%=link_to(h(book.title), book_path(book)) %></h2>
  <p><%= book.thoughts %></p>
<% end %>
 
<%= will_paginate @books %>

Помните наших помощников по URL из рейк-маршрутов? Мы используем book_path для генерации URL-адреса для действий show контроллера книги. Если вы не помните, проверьте маршруты рейка снова. link_to является помощником для создания тега ссылки. Теперь давайте запустим наш сервер и нажмем на приложение. Теперь у вас должно быть несколько уродливых синих ссылок. Нажмите на название вашей книги, и оно должно перейти в / books /: id aka BooksController # show:

Ссылки!

Время для отображения некоторых комментариев. Помните ту консольную сессию, которую мы провели немного назад? Одна из наших книг имеет несколько комментариев. давайте обновим наш контроллер, чтобы найти комментарии и наш show.html.erb для их отображения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
# books_controller.rb
def show
  @book = Book.find(params[:id])
  @comments = @book.comments
end
 
# show.html.erb
<% title @book.title %>
 
<h2><%=link_to(h(@book.title), book_path(@book)) %></h2>
<p><%= @book.thoughts %></p>
 
<% if @comments %>
  <h3>Comments</h3>
 
  <% for comment in @comments do %>
    <p><strong><%=h(comment.author) %></strong>: <%=h comment.text %>
  <% end %>
<% end %>

Поэтому мы назначаем @comments в контроллере для всех комментариев книги, а затем делаем цикл в представлении, чтобы отобразить их. Перейдите к / books / 1 (1 пришло из Book.find (1) в сеансе консоли). Проверь это:

Комментарии

Теперь нам нужна форма для создания нового комментария. Нам нужны две вещи. 1, контроллер комментариев, чтобы сохранить комментарий, и 2 маршрут к этому действию. давайте сначала займемся # 1.

1
bookshelf $ ./script/generate controller Comments

Создать действие, которое создает новый комментарий, устанавливает его атрибуты (текст / автора) из отправленных данных формы и сохраняет его.

1
2
3
4
5
6
7
8
9
class CommentsController < ApplicationController
  def create
    book = Book.find params[:book_id]
    comment = book.comments.new params[:comment]
    comment.save
    flash[:notice] = ‘Comment saved’
    redirect_to book_path(book)
  end
end

Сначала код находит книгу, затем создает новый комментарий в форме данных формы, сохраняет ее, устанавливает сообщение, а затем перенаправляет обратно на страницу этой книги. params содержит хэш всех данных GET / POST с запросом. Теперь нам нужно создать маршрут к действию контроллера. Откройте маршруты .rb:

1
2
3
4
5
ActionController::Routing::Routes.draw do |map|
  map.resources :books do |book|
    book.resources :comments, :only => :create
  end
end
01
02
03
04
05
06
07
08
09
10
11
12
13
bookshelf $ rake routes
# We needed to add a route to create a new comment for a book.
# book_comment is tied to our CommentsController#create
book_comments POST /books/:book_id/comments(.:format) {:controller=>»comments», :action=>»create»}
        books GET /books(.:format) {:controller=>»books», :action=>»index»}
              POST /books(.:format) {:controller=>»books», :action=>»create»}
     new_book GET /books/new(.:format) {:controller=>»books», :action=>»new»}
    edit_book GET /books/:id/edit(.:format) {:controller=>»books», :action=>»edit»}
         book GET /books/:id(.:format) {:controller=>»books», :action=>»show»}
              PUT /books/:id(.:format) {:controller=>»books», :action=>»update»}
              DELETE /books/:id(.:format) {:controller=>»books», :action=>»destroy»}
# every time you modify routes.rb you’ll need to restart the server
# kill the server process you have running with ^c (ctrl + c) and start it again

Вернитесь на страницу / books и убедитесь, что ничего не взорвалось. Все должно быть хорошо и модно. Теперь для построения формы. Нам нужна форма, которая отправляет данные POST в / book /: book_id / comments. К счастью, у Rails есть идеальный помощник для этого: form_for. form_for берет некоторые модели и генерирует маршрут для них. Мы передаем form_for блок для создания входных данных формы. Вставьте это в конец вашего show.html.erb:

01
02
03
04
05
06
07
08
09
10
<h3>Post Your Comment</h3>
<% form_for([@book, Comment.new]) do |form|
  <p><%= form.label :author %></p>
  <p><%= form.text_field :author %></p>
 
  <p><%= form.label :text, ‘Comment’ %></p>
  <p><%= form.text_area :text %></p>
 
  <%= form.submit ‘Save’ %>
<% end %>

Мы вызываем form_for, чтобы создать новую форму для комментария книги, а затем используем text_field / text_area для создания входных данных для атрибутов. На данный момент мы можем пойти дальше и сделать комментарий. Заполните форму и альт у вас теперь есть комментарии!

Мы можем комментировать!

Видишь эту зеленую вещь? Это вспышка. Флэш — это способ хранения сообщений между действиями. Это идеально подходит для хранения маленьких сообщений, как это. Но что нам делать, если в книге слишком много комментариев? Мы разбиваем их на страницы, как и раньше. Итак, давайте внесем некоторые изменения в контроллер и посмотрим:

1
2
3
4
5
# books_controller.rb
def show
  @book = Book.find(params[:id])
  @comments = @book.comments.paginate :page => params[:page], :per_page => 10, :order => ‘created_at ASC’
end
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# show.html.erb
 
<% title @book.title %>
 
<h2><%=link_to(h(@book.title), book_path(@book)) %></h2>
<p><%= @book.thoughts %></p>
 
<% if @comments %>
  <h3>Comments</h3>
 
  <% for comment in @comments do %>
    <p><strong><%=h(comment.author) %></strong>: <%=h comment.text %>
  <% end %>
 
  <%= will_paginate @comments %>
<% end %>
 
<h3>Post Your Comment</h3>
<% form_for([@book, Comment.new]) do |form|
  <p><%= form.label :author %></p>
  <p><%= form.text_field :author %></p>
 
  <p><%= form.label :text, ‘Comment’ %></p>
  <p><%= form.text_area :text %></p>
 
  <%= form.submit ‘Save’ %>
<% end %>

Начните комментировать свои книги, и вы должны увидеть несколько страниц.

Комментарии на странице

Теперь люди могут комментировать, и все разбито на страницы, но мы что-то упускаем. У нас нет веб-интерфейса для создания книг. Нам нужно создать форму для этого. Кроме того, мы являемся администратором, поэтому только я должен иметь право создавать книги. Это означает, что нам нужно создать пользователя, войти в систему и проверить, могут ли они выполнить какое-либо действие.


Теперь мы собираемся реализовать функциональность CRUD для администраторов. Сначала мы реализуем действия по созданию, редактированию и удалению книг. Затем мы создадим логин администратора. Наконец, мы убедимся, что только администраторы могут выполнять эти действия.

Создание новой книги требует двух новых действий. Одно действие, которое отображает форму для новой книги. Это действие называется «новый». Второй называется «создать». Это действие принимает параметры формы и сохраняет их в базе данных. Откройте файл books_controller.rb и добавьте следующие действия:

01
02
03
04
05
06
07
08
09
10
11
12
13
def new
  @book = Book.new
end
 
def create
  @book = Book.new params[:book]
  if @book.save
    flash[:notice] = «#{@book.title} saved.»
    redirect_to @book
  else
    render :new
  end
end

Нам также нужен новый вид, который показывает форму. Создайте новый файл /apps/views/books/new.html.erb и вставьте его:

01
02
03
04
05
06
07
08
09
10
11
12
13
<% form_for(@book) do |form|
  <p>
    <%= form.label :title %><br/>
    <%= form.text_field :title %>
  </p>
 
  <p>
    <%= form.label :thoughts %><br/>
    <%= form.text_area :thoughts %>
  </p>
 
  <%= form.submit %>
<% end %>

Теперь мы готовы создать новую книгу. Укажите в браузере / books / new, и вы должны увидеть эту форму. Идите головой и создайте новую книгу. После того, как вы заполните свою форму, вы должны увидеть новую книгу.

New Book Form
Saved book

Избавьтесь от двойного заголовка в /app/views/books/show.html.erb и добавьте несколько ссылок на действия, которые администратор может выполнить над этой книгой. Откройте этот файл и установите его содержимое:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<% title @book.title %>
 
<p><%= @book.thoughts %></p>
 
<% if @comments %>
  <h3>Comments</h3>
 
  <% for comment in @comments do %>
    <p><strong><%=h(comment.author) %></strong>: <%=h comment.text %>
  <% end %>
 
  <%= will_paginate @comments %>
<% end %>
 
<h3>Post Your Comment</h3>
%>
  <p><%= form.label :author %></p>
  <p><%= form.text_field :author %></p>
 
  <p><%= form.label :text, 'Comment' %></p>
  <p><%= form.text_area :text %></p>
 
  <%= form.submit 'Save' %>
<% end %>
 
<p>
  Admin Actions:
  <%= link_to 'Edit', edit_book_path(@book) %> |
  %>
</p>

Перейдите на страницу книги, и вы должны увидеть:

Updated book's page

Теперь, когда у нас есть ссылки для редактирования и удаления, вы можете их реализовать. Редактирование книги работает примерно так же, как создание новой. Нам нужно действие, которое показывает форму редактирования, и одно, чтобы сохранить изменения. Удалить — это всего лишь одно действие, которое удаляет запись из базы данных. Откройте books_controller.rb и добавьте следующие действия:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
def edit
  @book = Book.find params[:id]
end
 
def update
  @book = Book.find params[:id]
  if @book.update_attributes(params[:book])
    flash[:notice] = "#{@book.title} saved."
    redirect_to @book
  else
    render :edit
  end
end
 
def destroy
  book = Book.find params[:id]
  book.destroy
  flash[:notice] = "#{book.title} deleted."
  redirect_to books_path
end

Действие редактирования находит запрошенную книгу по идентификатору в URL. Действие обновления находит книгу по идентификатору и использует метод update_attributes для установки новых значений из формы. Удалить находит книгу по идентификатору и удаляет ее. Затем он перенаправляет вас обратно в список книг.

Далее мы должны создать форму редактирования. Эта форма точно такая же, как форма создания. Мы можем просто скопировать show.html.erb для edit.html.erb. Все, что мы собираемся сделать, это изменить название. Создайте новый файл в /app/views/books/edit.html.erb и вставьте это:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<% title "Editing #{@book.title}" %>
 
%>
  <p>
    <%= form.label :title %><br/>
    <%= form.text_field :title %>
  </p>
 
  <p>
    <%= form.label :thoughts %><br/>
    <%= form.text_area :thoughts %>
  </p>
 
  <%= form.submit %>
<% end %>

Теперь на одной из страниц книги нажмите на ссылку «Изменить». Вы должны увидеть знакомую форму:

Editing a book

Заметьте, как Rails заполняет входы сохраненными значениями? Хорошо, да. Сохраните некоторые изменения в книге. Когда вы закончите, вы должны увидеть это:

Viewing an edited book.

Теперь удали эту книгу. Вы должны получить диалоговое окно подтверждения, а затем перенаправиться обратно в / books.

Are you sure?Book deleted.

Добавьте ссылку для создания новой книги на странице указателя. Откройте /app/views/books/index.html.erb и добавьте его в конец:

1
2
3
<p>
  Admin actions: <%= link_to 'New Book', new_book_path %>
</p>

Теперь у нас есть функциональность CRUD. Нам нужно создать нашего администратора.

Поддержка пользовательских логинов — это решенная проблема в Rails. Вам редко приходится писать собственную систему аутентификации. Мы собираемся использовать аутентичный драгоценный камень. Authlogic предоставляет простую механику для аутентификации пользователей и хранения сессий. Это префект для нашего приложения. Нам нужен админ для входа в систему, чтобы он мог создавать / редактировать / удалять книги. Сначала давайте начнем с установки authlogic gem.

1
2
# add config.gem 'authlogic' in environment.rb
bookshelf $ sudo rake gems:install

Создайте новую модель для администраторов. Поскольку наши пользователи являются только администраторами, мы назовем модель Admin. На данный момент модель нуждается только в атрибуте входа. Генерация модели с использованием скрипта / генерации модели:

1
2
3
4
5
6
7
8
9
bookshelf $ ./script/generate model Admin login:string
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/admin.rb
create test/unit/admin_test.rb
create test/fixtures/admins.yml
exists db/migrate
create db/migrate/20091204202129_create_admins.rb

Теперь добавьте специфичные для authlogic столбцы в нашу модель администратора. Откройте миграцию, которую вы только что создали, и вставьте в нее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
class CreateAdmins < ActiveRecord::Migration
  def self.up
    create_table :admins do |t|
      t.string :login     
      t.string :crypted_password, :null => false
      t.string :password_salt, :null => false
      t.string :persistence_token, :null => false     
      t.timestamps
    end
  end
 
  def self.down
    drop_table :admins
  end
end

Теперь перенесите вашу базу данных.

1
2
3
4
5
bookshelf $ rake db:migrate
== CreateAdmins: migrating ===================================================
-- create_table(:admins)
   -> 0.0025s
== CreateAdmins: migrated (0.0026s) ==========================================

Теперь модель администратора создана. Далее нам нужно создать аутентичную сессию для этого администратора. Authlogic включает в себя генератор для этого:

1
2
3
bookshelf $ ./script/generate session admin_session
exists app/models/
create app/models/admin_session.rb

Далее нам нужно создать несколько маршрутов для входа и выхода. Откройте route.rb и добавьте эту строку:

1
map.resource :admin_session

Теперь нам нужен контроллер для обработки входа и выхода. Сгенерируйте этот контроллер, используя генератор:

01
02
03
04
05
06
07
08
09
10
bookshelf $ ./script/generate controller AdminSessions
exists app/controllers/
exists app/helpers/
create app/views/admin_sessions
exists test/functional/
exists test/unit/helpers/
create app/controllers/admin_sessions_controller.rb
create test/functional/admin_sessions_controller_test.rb
create app/helpers/admin_sessions_helper.rb
create test/unit/helpers/admin_sessions_helper_test.rb

Теперь откройте /app/controllers/admin_sessions_controller.rb и вставьте его в него:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
class AdminSessionsController < ApplicationController 
  def new
    @admin_session = AdminSession.new
  end
 
  def create
    @admin_session = AdminSession.new(params[:admin_session])
    if @admin_session.save
      flash[:notice] = "Login successful!"
      redirect_to books_path
    else
      render :action => :new
    end
  end
 
  def destroy
    current_admin_session.destroy
    flash[:notice] = "Logout successful!"
    redirect_to books_path
  end
end

Вот это да!Кажется, что мы только что сделали много, но мы не сделали. Мы только что создали 2 новые модели. Одна модель содержит информацию о наших администраторах, а другая — информацию о сеансе администратора. Наконец, мы создали контроллер для обработки входа и выхода. Теперь нам нужно представление, чтобы показать форму входа. Создайте новый файл в /app/views/admin_sessions/new.html.erb и вставьте его в него:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<% title 'Login' %>
 
%>
  <%= f.error_messages %>
  <p>
    <%= f.label :login %><br />
    <%= f.text_field :login %>
  </p>
 
  <p>
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </p>
 
  <%= f.submit "Login" %>
<% end %>

Мы почти закончили.Нам все еще нужно сообщить нашей модели Admin, что она использует authlogic, и добавить некоторую логику в наш контроллер приложений для поддержки информации о сеансе. Все контроллеры наследуются от application_controller, так что это хороший способ обмена методами между контроллерами. Откройте /app/controllers/application_controller.rb и вставьте это:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
 
  # Scrub sensitive parameters from your log
  # filter_parameter_logging :password
 
  filter_parameter_logging :password, :password_confirmation
  helper_method :current_admin_session, :current_admin
 
  private
  def current_admin_session
    return @current_admin_session if defined?(@current_admin_session)
    @current_admin_session = AdminSession.find
  end
 
  def current_admin
    return @current_admin if defined?(@current_admin)
    @current_admin = current_admin_session && current_admin_session.user
  end
end

Теперь в /app/models/admin.rb добавьте эту строку внутри класса:

1
2
# /app/models/admin.rb
acts_as_authentic

Мы наконец готовы войти и выйти. Все, что мы делали, было почти чисто из примеров аутентичной документации. Это стандартная настройка для многих приложений. Если вы хотите узнать больше о том, как работает authlogic, вы можете здесь . Вот список того, что мы сделали.

  1. Установите аутентичный драгоценный камень
  2. Создайте модель администратора для хранения базовой информации, такой как логин / пароль
  3. Добавить специфичные для authlogic столбцы в таблицу Admin
  4. Сгенерировал авторизованный сеанс администратора
  5. Созданы маршруты для входа и выхода
  6. Создан контроллер AdminSession для выполнения всей работы
  7. Создан вид, который показывает форму входа
  8. Добавлены методы в ApplicationController для сохранения сессий
  9. Сказал модель Admin, что она использует authlogic

Пришло время создать учетную запись администратора. Наше приложение простое и имеет только одного администратора. Поскольку у нас только один администратор, мы можем легко использовать консоль. Поскольку нам потребуется заново создать этого пользователя позже при развертывании, нет смысла делать одно и то же дважды. В Rails теперь есть функциональность для заполнения базы данных. Это идеально подходит для создания начальных записей. Существует файл /db/seeds.rb, где вы можете написать код ruby ​​для создания ваших начальных моделей. Затем вы можете запустить этот файл через rake db: seed. Для создания нашей модели администратора нам понадобится логин, пароль и подтверждение пароля. Откройте /db/seeds.rb и вставьте это. Введите логин с именем, которое вы хотите.

1
Admin.create! :login => 'Adam', :password => 'nettuts', :password_confirmation => 'nettuts'

Мы используем создание! метод, потому что он выдаст исключение, если запись не может быть сохранена. Идите вперед и запустите задачу rake, чтобы заполнить базу данных:

1
bookshelf $ rake db:seed

Теперь мы должны быть в состоянии войти. Перезапустите сервер, чтобы получить новые маршруты. Перейдите в / admin_session / new. Тебе следует увидеть:

Форма входа

Идите вперед и заполните его, и теперь вы должны войти!

ZOMG logged in!

Теперь, когда администраторы могут войти, мы можем предоставить им доступ к новым функциям / редактировать / удалять. В Rails есть такие замечательные вещи, как фильтры. Фильтры — это то, что вы можете делать в точках жизненного цикла запроса. Самый популярный фильтр — это before_filter. Этот фильтр выполняется перед действием в контроллере. Мы можем создать фильтр before в контроллере books, который проверяет, вошли ли мы в систему admin. Фильтр будет перенаправлять пользователей, которые не вошли в систему, что предотвращает несанкционированный доступ. Откройте books_controller.rb и добавьте следующие строки:

01
02
03
04
05
06
07
08
09
10
11
# first line inside the class:
before_filter :login_required, :except => [:index, :show]
 
# after all the actions
private
def login_required
  unless current_admin
    flash[:error] = 'Only logged in admins an access this page.'
    redirect_to books_path
  end
end

Now we need to update our views to show the admin links only if there’s an admin logged in. That’s easy enough. All we need to do is wrap it in an if.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
# show.html.erb
<% if current_admin %>
<p>
  Admin Actions:
  <%= link_to 'Edit', edit_book_path(@book) %> |
  %>
</p>
<% end %>
 
# index.html.erb
<% if current_admin %>
<p>
  Admin actions: <%= link_to 'New Book', new_book_path %>
</p>
<% end %>

We still need to add a login/logout link. That should go on every page. An easy way to put something on every page is add it to the layout.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# /app/views/layouts/application.erb
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict//EN»
  «http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>
<html>
  <head>
    <title><%= h(yield(:title) || "Untitled") %></title>
    <%= stylesheet_link_tag 'application' %>
    <%= yield(:head) %>
  </head>
  <body>
    <div id=»container»>
      <%- flash.each do |name, msg| -%>
        <%= content_tag :div, msg, :id => "flash_#{name}" %>
      <%- end -%>
 
      <%- if show_title? -%>
        <h1><%=h yield(:title) %></h1>
      <%- end -%>
 
      <%= yield %>
 
      <% if current_admin %>
        <p><%= link_to 'Logout', admin_session_path(current_admin_session), :method => :delete %></p>
      <% else %>
        <p><%= link_to 'Login', new_admin_session_path %></p>
      <% end %>
    </div>
  </body>
</html>

Now you should have login/logout links on pages depending if your logged in and logged out. Go ahead and click the through the app. Try access the new book page after you’ve logged out. You should see an error message.

Access Denied

Click through the app. You should be able to login and out, and edit/create/delete books. Time for the final step. Let’s add some formatting to your thoughts and user comments. Rails has a helper method that will change new lines to line breaks and that sorta thing. Add that show.html.erb:

1
2
3
4
5
6
7
# <p><%= @book.thoughts %></p> becomes
<%= simple_format @book.thoughts %>
 
# do the same thing for comments
# <p><strong><%=h(comment.author) %></strong>: <%=h comment.text %> becomes
<p><strong><%=h(comment.author) %></strong>:</p>
<%= simple_format comment.text %>

It doesn’t make sense to put the thoughts in the index, so let’s replace that with a preview instead of the entire text.

1
2
3
# index.html.erb
# <p><%= book.thoughts %></p> becomes
<%= simple_format(truncate(book.thoughts, 100)) %>

Now our final index page should look like this:

Easier index.

Finally we need to set up a route for our root page. Open up routes.rb and add this line:

1
map.root :controller => 'books', :action => 'index'

Now when you go to / you’ll see the book listing.

Now we are going to deploy this app in a few steps. You don’t need your own server or anything like that. All you need is an account on Heroku . Heroku is a cloud Rails hosting service. If you have a small app, you can use their service for free. Once you’ve signed up for an account, install the heroku gem:

1
$ sudo gem install heroku

Heroku works with git. Git is a distributed source control management system. In order to deploy to heroku all you need to do is create your app then push your code to it’s server. If you haven’t already install git, instructions can be found here . Once you have heroku and git installed you are ready to deploy. First thing we need to do is create a new git repo out of your project:

1
2
bookshelf $ git init
Initialized empty Git repository in /Users/adam/Code/bookshelf/.git/

It’s time to do some preparation for heroku deployment. In order to get your application’s gems installed, create a .gems file in the root project directory. Each line has the name of the gem on it. When you push your code to heroku it will read the .gems file and install the gems for you. So create a .gems file and paste this into it:

1
2
3
forgery
will_paginate
authlogic

There is a problem with authlogic on heroku, so we need to create an initializer to require the gem for us. Create a new file in /config/initializers/authlogic.rb and put this line in there:

1
require 'authlogic'

Now we should be ready to deploy. First thing you’re going to do is run heroku create. This will create a new heroku app for you. If you’re a first time user, it will guide you through the setup process.

1
2
bookshelf $ heroku create  
Git remote heroku added

No we are ready to deploy. Here are the steps

  1. Add all files in the project to a commit
  2. Commit the files
  3. Push are code to heroku
  4. Migrate the database on heroku
  5. Seed the database on heroku
  6. Restart the heroku server
  7. Open your running application
1
2
3
4
5
6
7
bookshelf $ git add -A
bookshelf $ git commit -m 'Initial commit'
bookshelf $ git push heroku master
bookshelf $ heroku rake db:migrate
bookshelf $ heroku rake db:seed
bookshelf $ heroku restart
bookshelf $ heroku open

Here is the finally app running on the world wide web:

Deployed

We’ve covered a lot of ground in this article, so where do we go from here? There are few things we didn’t do in this app. We didn’t add any validations to the models. We didn’t use partials. We didn’t do any administration for the comments. These are things you should look into next. Here are some links to help you with the next steps.

  • Completed Source Code
  • Confused about the form parts? Read this
  • Confused about routes? Read this
  • Confused about heroku? Read this
  • Confused about associations? Read this
  • Confused about authlogic? Read this

Links to gems used in this project.

  • Подпишитесь на нас в Твиттере или подпишитесь на ленту Nettuts + RSS для получения лучших учебных материалов по веб-разработке. готов

Готовы поднять свои навыки на новый уровень и начать зарабатывать на своих скриптах и ​​компонентах? Проверьте наш родной рынок, CodeCanyon .

CodeCanyon

Знаете ли вы, что вы можете заработать до 600 долларов за написание учебника PLUS и / или скринкаст для нас? Мы ищем подробные и хорошо написанные учебники по HTML, CSS, PHP и JavaScript. Если у вас есть такая возможность, пожалуйста, свяжитесь с Джеффри по адресу [email protected].

Обратите внимание, что фактическая компенсация будет зависеть от качества окончательного урока и скринкаста.

Написать ПЛЮС учебник