Как создать приложение Ruby on Rails в Ubuntu 22.04
Введение
Рубин. В нем используется самоуверенный подход к разработке приложений, предполагающий, что установленные соглашения лучше всего служат разработчикам там, где есть общая цель. Поэтому Rails предлагает соглашения для обработки маршрутизации, данных с отслеживанием состояния, управления активами и т. д., чтобы обеспечить базовую функциональность, необходимую большинству веб-приложений.
Rails следует за повторяющимся без необходимости.
В этом руководстве вы создадите приложение Rails, которое позволит пользователям публиковать информацию об акулах и их поведении. Этот проект послужит отправной точкой для будущей разработки приложений.
Предпосылки
Чтобы следовать этому руководству, вам понадобятся:
- Локальный компьютер или сервер разработки под управлением Ubuntu 22.04. На вашем компьютере для разработки должен быть пользователь без полномочий root с правами администратора и брандмауэр, настроенный с помощью
ufw
. Инструкции по настройке см. в нашем руководстве Initial Server Setup with Ubuntu 22.04. - Как установить Node.js в Ubuntu 22.04.
- Ruby, Как установить Ruby on Rails с помощью rbenv в Ubuntu 22.04. В этом руководстве используются Ruby 3.2.0, rbenv 1.2.0-52 и Rails 7.0.4.
Установив Node.js, Ruby, rbenv и Rails, вы готовы установить базу данных для своего приложения.
Шаг 1 — Установка SQLite3
Прежде чем создавать приложение для акул Rails, вам понадобится база данных для хранения пользовательских данных. Rails настроен на использование SQLite по умолчанию, и это часто является хорошим выбором при разработке. Поскольку данные приложения не требуют программной расширяемости высокого уровня, SQLite удовлетворит потребности приложения.
Во-первых, внутри вашего терминала обновите индекс вашего пакета:
- sudo apt update
Затем установите пакеты sqlite3
и libsqlite3-dev
:
- sudo apt install sqlite3 libsqlite3-dev
Это установит как SQLite, так и необходимые файлы разработки.
Вы можете проверить версию, чтобы убедиться, что установка прошла успешно:
- sqlite3 --version
Output3.37.2 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5dalt1
Установив SQLite, вы готовы приступить к разработке своего приложения.
Шаг 2 — Создание нового проекта Rails
Установив базу данных, вы можете создать новый проект Rails и получить доступ к некоторому шаблонному коду по умолчанию, который предлагает Rails, с помощью команды rails new
.
Создайте проект с именем sharkapp
с помощью следующей команды:
- rails new sharkapp
Вывод показывает все различные вещи, которые Rails создает для вашего нового проекта. В следующем выводе выделены некоторые важные файлы, каталоги и команды:
Output create
. . .
create Gemfile
. . .
create app
. . .
create app/controllers/application_controller.rb
. . .
create app/models/application_record.rb
. . .
create app/views/layouts/application.html.erb
. . .
create config
create config/routes.rb
create config/application.rb
. . .
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
. . .
create config/database.yml
create db
create db/seeds.rb
. . .
run bundle install
. . .
Bundle complete! 15 Gemfile dependencies, 69 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
. . .
Вот краткое описание некоторых созданных файлов и папок Rails:
Gemfile
: в этом файле перечислены зависимости gem для вашего приложения. gem — это программный пакет Ruby, а Gemfile позволяет вам управлять программными потребностями вашего проекта.app
: в каталогеapp
находится основной код вашего приложения. Сюда входят модели, контроллеры, представления, активы, помощники и почтовые программы, составляющие само приложение. Rails предоставляет вам некоторый шаблон уровня приложения для запуска модели MVC в таких файлах, какapp/models/application_record.rb
,app/controllers/application_controller.rb
иapp/views/layouts/application.html.erb
.config
: этот каталог содержит настройки конфигурации вашего приложения:config/routes.rb
: объявления маршрутов вашего приложения находятся в этом файле.config/application.rb
: в этом файле находятся общие настройки компонентов вашего приложения.
Наконец, Rails запускает команду
bundle install
для установки зависимостей, перечисленных в вашемGemfile
.Когда все настроено, перейдите в новый каталог
sharkapp
:- cd sharkapp
Внутри каталога sharkapp запустите сервер Rails, чтобы убедиться, что ваше приложение работает, с помощью команды
rails server
. Если вы работаете на своем локальном компьютере, введите следующий код, чтобы запустить сервер:- rails server
Rails по умолчанию привязывается к
localhost
, то есть вы можете получить доступ к своему приложению, перейдя наlocahost:3000
в своем браузере:Если вы работаете на сервере разработки, сначала убедитесь, что соединения разрешены на порту
3000
:- sudo ufw allow 3000
Затем запустите сервер с флагом
--binding
для привязки к IP-адресу вашего сервера:- rails server --binding=your_server_ip
Перейдите в браузере по адресу
http://your_server_ip:3000
, чтобы получить доступ к целевой странице Rails по умолчанию.Когда вы будете готовы, вы можете остановить сервер, нажав
CTRL+C
в своем терминале.Когда ваше приложение создано и установлено, вы готовы приступить к созданию уникального приложения на основе шаблона Rails.
Шаг 3 — Создание шаблона приложения
Чтобы создать приложение-акулу, вам нужно создать модель для управления данными приложения, представления, чтобы пользователь мог взаимодействовать с этими данными, и контроллер для управления связью между моделью и представлениями. Чтобы построить их, используйте команду
rails generate scaffold
. При этом создается модель, операции создания, чтения, обновления и удаления (CRUD) для приложения, а также шаблоны для частей, помощников и тестов.Команда
generate scaffold
выполняет множество операций. Команда включает имя модели и поля, которые вы хотите добавить в таблицу базы данных. Rails использует класс Ruby, а также наследует классActiveRecord::Base
. Это означает, что вы можете работать с классом модели так же, как с классом Ruby. Кроме того, вы также можете использовать методы из Active Record. Active Record гарантирует, что каждый класс сопоставляется с таблицей в вашей базе данных, а каждый экземпляр этого класса — со строкой в этой таблице.Выполните следующую команду, чтобы сгенерировать модель
Shark
, контроллер и связанные представления:- rails generate scaffold Shark name:string facts:text
Параметры
name:string
иfacts:text
в этой команде указывают поля, которые вы создаете в таблице базы данных, и тип данных, которые они должны принимать. Оба дают вам возможность ввести то, что вы хотели бы. Опцияtext
позволяет использовать больше символов.После ввода этой команды вывод показывает все различные сгенерированные файлы:
Outputinvoke active_record create db/migrate/20190804181822_create_sharks.rb create app/models/shark.rb . . . invoke resource_route route resources :sharks invoke scaffold_controller create app/controllers/sharks_controller.rb invoke erb create app/views/sharks create app/views/sharks/index.html.erb create app/views/sharks/edit.html.erb create app/views/sharks/show.html.erb create app/views/sharks/new.html.erb create app/views/sharks/_form.html.erb . . .Rails создал модель в
app/models/shark.rb
и выполнил перенос базы данных:db/migrate/20190804181822_create_sharks.rb
. Отметка времени в вашем файле миграции будет отличаться от выходных данных примера.Он также создал контроллер
app/controllers/sharks_controller.rb
, а также представления, связанные с операциями CRUD вашего приложения, собранные в разделеapp/views/sharks
. Среди этих представлений есть партиал,_form.html.erb
, который содержит код, используемый во всех представлениях.Наконец, Rails добавила новый ресурсный маршрут,
resources :sharks
, вconfig/routes.rb
. Это позволяет маршрутизатору Rails сопоставлять входящие HTTP-запросы с контроллеромsharks
и связанными с ним представлениями.Хотя Rails проделал большую часть работы по построению кода приложения, стоит углубиться в некоторые файлы, чтобы лучше понять, что происходит.
Чтобы понять файл контроллера, введите в терминале следующую команду:
- cat app/controllers/sharks_controller.rb
Outputclass SharksController < ApplicationController before_action :set_shark, only: %i[ show edit update destroy ] # GET /sharks or /sharks.json def index @sharks = Shark.all end # GET /sharks/1 or /sharks/1.json def show end # GET /sharks/new def new @shark = Shark.new end # GET /sharks/1/edit def edit end # POST /sharks or /sharks.json def create @shark = Shark.new(shark_params) respond_to do |format| if @shark.save format.html { redirect_to shark_url(@shark), notice: "Shark was successfully created." } format.json { render :show, status: :created, location: @shark } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @shark.errors, status: :unprocessable_entity } end end end # PATCH/PUT /sharks/1 or /sharks/1.json def update respond_to do |format| if @shark.update(shark_params) format.html { redirect_to shark_url(@shark), notice: "Shark was successfully updated." } format.json { render :show, status: :ok, location: @shark } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @shark.errors, status: :unprocessable_entity } end end end # DELETE /sharks/1 or /sharks/1.json def destroy @shark.destroy respond_to do |format| format.html { redirect_to sharks_url, notice: "Shark was successfully destroyed." } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_shark @shark = Shark.find(params[:id]) end # Only allow a list of trusted parameters through. def shark_params params.require(:shark).permit(:name, :facts) end endКонтроллер отвечает за управление тем, как информация извлекается и передается в связанную с ней модель, а также за то, как она связывается с конкретными представлениями. Например, контроллер
sharks
включает ряд методов, которые примерно соответствуют стандартным операциям CRUD. Существует больше методов, чем функций CRUD, чтобы обеспечить эффективность в случае ошибок.Например, рассмотрим метод
create
:. . . def create @shark = Shark.new(shark_params) respond_to do |format| if @shark.save format.html { redirect_to @shark, notice: 'Shark was successfully created.' } format.json { render :show, status: :created, location: @shark } else format.html { render :new } format.json { render json: @shark.errors, status: :unprocessable_entity } end end end . . .
Если новый экземпляр класса
Shark
успешно сохранен,redirect_to
создаст новый запрос, который затем будет направлен контроллеру. Это запросGET
, и он будет обработан методомshow
, который покажет пользователю ввод, который он недавно добавил.В случае сбоя Rails снова отобразит шаблон
app/views/sharks/new.html.erb
, а не сделает еще один запрос к маршрутизатору, давая пользователям еще одну возможность отправить свои данные.В дополнение к контроллеру
sharks
Rails создал шаблон для представленияindex
, который сопоставляется с методомindex
в вашем контроллере. Вы будете использовать это как корневое представление для своего приложения.Выполните следующую команду, чтобы вывести файл:
- cat app/views/sharks/index.html.erb
Output<p style="color: green"><%= notice %></p> <h1>Sharks</h1> <div id="sharks"> <% @sharks.each do |shark| %> <%= render shark %> <p> <%= link_to "Show this shark", shark %> </p> <% end %> </div> <%= link_to "New shark", new_shark_path %>Представление
index
перебирает экземпляры вашего классаShark
, который сопоставляется с таблицейsharks
в вашей базе данных. Используя шаблон ERB, представление выводит каждое поле из таблицы, связанное с отдельным экземпляром акулы:name
иfacts
.Затем представление использует помощники, которые стали доступны вам, когда вы определили ресурсный маршрут
sharks
с помощью командыrails generate scaffold
.Представление
new
использует так называемые частичные элементы. Выполните следующую команду, чтобы вернуть шаблонapp/views/sharks/new.html.erb
:- cat app/views/sharks/new.html.erb
Output<h1>New shark</h1> <%= render "form", shark: @shark %> <br> <div> <%= link_to "Back to sharks", sharks_path %> </div>Хотя в этом шаблоне может показаться, что в нем отсутствуют поля ввода для новой записи акулы, ссылка на
форму рендеринга
указывает на то, что шаблон извлекает партиал_form.html.erb
, который извлекает код, который повторяется в представлениях.Выведите файл
_form.html.erb
, чтобы получить более полное представление о том, как создается новый экземпляр акулы:- cat app/views/sharks/_form.html.erb
Output<%= form_with(model: shark) do |form| %> <% if shark.errors.any? %> <div style="color: red"> <h2><%= pluralize(shark.errors.count, "error") %> prohibited this shark from being saved:</h2> <ul> <% shark.errors.each do |error| %> <li><%= error.full_message %></li> <% end %> </ul> </div> <% end %> <div> <%= form.label :name, style: "display: block" %> <%= form.text_field :name %> </div> <div> <%= form.label :facts, style: "display: block" %> <%= form.text_area :facts %> </div> <div> <%= form.submit %> </div> <% end %>В этом шаблоне используется помощник формы. Помощники форм предназначены для облегчения создания новых объектов на основе пользовательского ввода с использованием полей и области действия определенных моделей. В этом примере
form_with
принимаетmodel: shark
в качестве аргумента, а новый объект построителя форм, который он создает, имеет поля ввода, соответствующие полям вsharks
таблица. Это означает, что у пользователей есть поля формы для ввода как акулыname
, так и акулыfacts
.Отправка этой формы создаст ответ JSON с пользовательскими данными, к которым остальная часть вашего приложения может получить доступ с помощью метода params. Это создает объект
ActionController::Parameters
с этими данными.Теперь, когда вы знаете, что создал для вас
rails generate scaffold
, вы можете перейти к настройке корневого представления для вашего приложения.Шаг 4 — Создание корневого представления приложения и тестирование функциональности
В идеале вы хотите, чтобы целевая страница вашего приложения сопоставлялась с корнем приложения, чтобы пользователи могли сразу понять назначение приложения.
Например, вы можете создать контроллер
Welcome
и связанное с ним представлениеindex
, которое предоставляет пользователям общую целевую страницу, которая также может ссылаться на различные части приложения.Чтобы настроить это, вам нужно изменить параметры маршрутизации в
config/routes.rb
, чтобы указать корень приложения.Откройте
config/routes.rb
для редактирования с помощьюnano
или вашего любимого редактора:- nano config/routes.rb
Rails.application.routes.draw do resources :sharks # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Defines the root path route ("/") # root "articles#index" end
Без указания чего-либо более конкретного представление по умолчанию в
http://localhost:3000
илиhttp://your_server_ip:3000
будет использоваться по умолчанию. Страница приветствия Rails.Чтобы сопоставить корневое представление приложения с представлением
index
контроллера акул, раскомментируйте строку#root articles#index
по умолчанию, удалив#
и заменивarticle
наshark
:Rails.application.routes.draw do resources :sharks root 'sharks#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
Сохраните файл и выйдите из редактора, когда закончите редактирование. Если вы использовали
nano
для выхода из файла, нажмитеCTRL+X
,Y
, затемENTER
Теперь, когда пользователи переходят в корень вашего приложения, они переходят на целевую страницу акулы, а не на целевую страницу Rails по умолчанию. Кроме того, теперь у них есть возможность создать новую запись об акуле, просмотреть существующие записи, а также отредактировать или удалить заданные записи.
Затем запустите миграцию с помощью следующей команды:
- rails db:migrate
Этот вывод подтверждает миграцию:
Output== 20230124215633 CreateSharks: migrating ===================================== -- create_table(:sharks) -> 0.0041s == 20230124215633 CreateSharks: migrated (0.0045s) ============================Запустите свой сервер Rails снова. Если вы работаете локально, запустите:
- rails s
На сервере разработки запустите:
- rails s --binding=your_server_ip
Перейдите к
localhost:3000
, если вы работаете локально, илиhttp://your_server_ip:3000
, если вы работаете на сервере разработки, чтобы получить доступ к новой целевой странице:Чтобы создать новую акулу, щелкните ссылку «Новая акула». Эта ссылка приведет вас к маршруту
sharks/new
:Вы можете добавить некоторую информацию для тестирования вашего приложения. Напишите «Великий белый» в поле «Имя» и «Страшно» в поле «Факты»:
Затем нажмите кнопку «Создать акулу», чтобы создать акулу.
Эта кнопка направляет вас к маршруту
show
, который благодаря фильтруbefore_action
устанавливается с помощью методаset_shark
, который захватываетid
созданной вами акулы:class SharksController < ApplicationController before_action :set_shark, only: %i[ show edit update destroy ] . . . # GET /sharks/1 or /sharks/1.json def show end . . . private # Use callbacks to share common setup or constraints between actions. def set_shark @shark = Shark.find(params[:id]) end . . .
Вы можете протестировать функцию редактирования, нажав «Редактировать эту акулу» в записи об акуле. Это приведет вас к маршруту
edit
для этой акулы:Обновите
факты
о большой белой акуле, указав «Большой» вместо «Страшный», затем нажмите «Обновить акулу». Это вернет вас к маршрутуshow
:Наконец, нажав «Назад к акулам», вы перейдете к обновленному представлению
index
:Теперь, когда вы протестировали основные функции своего приложения, вы можете добавить некоторые проверки и проверки безопасности, чтобы сделать все более безопасным.
Шаг 5 — Добавление проверок
Ваше приложение-акула может принимать данные от пользователей, но представьте себе случай, когда пользователь пытается создать акулу, не добавляя к ней фактов, или создает запись для акулы, которая уже есть в базе данных. Вы можете создавать механизмы для проверки данных до того, как они будут введены в базу данных, добавляя проверки к своим моделям. Поскольку логика вашего приложения находится в его моделях, уместна проверка ввода данных.
Обратите внимание, что это руководство не охватывает написание проверочных тестов, но вы можете узнать больше о тестировании, ознакомившись с документацией по Rails.
Если вы еще не остановили сервер, остановите сервер сейчас, нажав
CTRL+C
в своем терминале.Откройте файл модели
shark.rb
:- nano app/models/shark.rb
В настоящее время файл сообщает нам, что класс
Shark
наследуется отApplicationRecord
, который, в свою очередь, наследуется отActiveRecord::Base
:class Shark < ApplicationRecord end
Добавьте несколько проверок в поле
name
, чтобы убедиться, что поле заполнено и что запись уникальна, что предотвращает дублирование записей:class Shark < ApplicationRecord validates :name, presence: true, uniqueness: true end
Затем добавьте проверку для поля
facts
, чтобы убедиться, что оно тоже заполнено:class Shark < ApplicationRecord validates :name, presence: true, uniqueness: true validates :facts, presence: true end
Строка кода
validates: факты, присутствие: истина
не касается уникальности фактов. Он подтверждает свою связь с уникальными записями об акулах.Сохраните и закройте файл, когда закончите.
Запустите свой сервер еще раз с помощью
rails s
илиrails s --binding=your_server_ip
, затем перейдите к корневому каталогу вашего приложения вhttp://localhost:3000
илиhttp://ваш_сервер_ip:3000
.Нажмите на ссылку «Новая акула». В форме добавьте «Великая белая» в поле «Имя» и «Большие зубы» в поле «Факты», затем нажмите «Создать акулу». В этом случае появляется предупреждающее сообщение:
Чтобы проверить другую проверку, нажмите «Вернуться к акулам», чтобы вернуться на домашнюю страницу, затем снова нажмите «Новая акула». В новой форме введите «Тигровая акула» в поле «Имя» и оставьте «Факты» пустым. Когда вы нажимаете «Создать акулу», выводится следующее предупреждение:
С этими изменениями ваше приложение имеет некоторые проверки для обеспечения согласованности данных, которые сохраняются в базе данных. Теперь вы можете обратить внимание на пользователей вашего приложения и определить, кто может изменять данные приложения.
Шаг 6 — Добавление аутентификации
С некоторыми проверками у вас есть некоторые гарантии в отношении данных, которые сохраняются в базе данных. Но как насчет пользователей? Если вы не хотите, чтобы все пользователи добавляли в базу данных, вам следует добавить некоторые меры аутентификации, чтобы гарантировать, что только разрешенные пользователи могут добавлять акул. Для этого используйте метод
http_basic_authenticate_with
, который позволяет создавать комбинацию имени пользователя и пароля для аутентификации пользователей.Существует несколько способов аутентификации пользователей в Rails, включая работу с гемами
devise
. Однако сейчас добавьте в контроллер приложения метод, который будет применяться к действиям в вашем приложении. Это будет полезно, если вы добавите в приложение больше контроллеров в будущем.Остановите сервер с помощью
CTRL+C
.Откройте файл, определяющий ваш
ApplicationController
:- nano app/controllers/application_controller.rb
Внутри находится определение класса
ApplicationController
, от которого наследуются другие контроллеры в вашем приложении:class ApplicationController < ActionController::Base end
Для аутентификации пользователей используйте жестко заданные имя пользователя и пароль с помощью метода
http_basic_authenticate_with
. Добавьте в файл следующий код:class ApplicationController < ActionController::Base http_basic_authenticate_with name: 'sammy', password: 'shark', except: [:index, :show] end
Помимо указания здесь имени пользователя и пароля, вы также ограничили аутентификацию, указав маршруты, где она не требуется:
index
иshow
. Другим способом добиться этого было бы написатьonly: [:create, :update, :destroy]
. Таким образом, все пользователи смогут получить доступ ко всем акулам и прочитать факты о конкретных акулах. Однако когда дело доходит до изменения содержимого сайта, пользователям необходимо будет доказать, что у них есть доступ.В более надежной настройке вы бы не хотели жестко кодировать значения таким образом, но этот пример демонстрирует, как вы можете включить аутентификацию для маршрутов вашего приложения. Rails хранит данные сеанса по умолчанию в файлах cookie: после того, как вы аутентифицируетесь в указанном действии, вам не потребуется повторно аутентифицироваться в том же сеансе.
Сохраните и закройте
app/controllers/application_controller.rb
, когда закончите редактирование. Теперь вы можете протестировать аутентификацию в действии.Запустите сервер с помощью
rails s
илиrails s --binding=your_server_ip
и перейдите к своему приложению по адресуhttp:// localhost:3000
илиhttp://ваш_сервер_ip:3000
.На целевой странице нажмите кнопку «Новая акула». Это вызовет следующее окно аутентификации:
Если вы введете имя пользователя
sammy
и парольshark
, которые являются комбинацией, которую вы добавили вapp/controllers/application_controller.rb
, вы будете в состоянии безопасно создать новую акулу.Теперь у вас есть работающее приложение для акул с проверкой данных и базовой схемой аутентификации.
Заключение
Приложение Rails, которое вы создали в этом руководстве, является отправной точкой, которую вы можете использовать для дальнейшей разработки. Если вы заинтересованы в изучении экосистемы Rails, документация проекта — отличное место для начала.
Вы также можете узнать больше о добавлении вложенных ресурсов в свой проект, прочитав How To Create Nested Resources for a Ruby on Rails Application, где показано, как создавать модели и маршруты вашего приложения.
Кроме того, вы можете изучить, как настроить более надежный интерфейс для вашего проекта с помощью такой структуры, как «Как настроить проект Ruby on Rails с интерфейсом React», в которой приведены рекомендации о том, как это сделать.
Если вы хотите изучить различные параметры базы данных, вы также можете ознакомиться с учебными пособиями по PostgreSQL, чтобы узнать больше о работе с этой базой данных.