Worker にウェブビューを実装する
最後に、ウェブビューを実装します。
準備
(↑クリックで拡大表示)
この Todo ウェブアプリでは、React と Bootstrap を使って、ウェブビューを実装します。
React と Bootstrap の実際の使用にあたっては、react-rails と twitter-bootstrap-rails という gem を使用します。まずは、この gem を使用する準備をしましょう。
ファイル Gemfile
の最後に、react-rails
と twitter-bootstrap-rails
の gem をインストールする記述を追加します。
source 'https://rubygems.org'
:
(中略)
:
gem 'react-rails', '~> 1.5.0'
gem 'twitter-bootstrap-rails', '~> 3.2.0'
bundle install
コマンドで、追加の gem をインストールします。
bundle install
rails generate bootstrap:install
コマンドを使って、twitter-bootstrap-rails
を Rails から使えるようにします。
bundle exec rails generate bootstrap:install static
rails generate react:install
コマンドを使って、react-rails
を Rails から使えるようにします。
bundle exec rails generate react:install
これで、準備完了です。
ウェブビューの実装
(↑クリックで拡大表示)
rails generate react:component
コマンドを使って、コンポーネントのテンプレートを生成します。コンポーネント名は、MiniTodo
とします。
bundle exec rails generate react:component MiniTodo
続いて、MiniTodo コンポーネントの中身を定義していきます。生成されたファイル app/assets/javascripts/components/mini_todo.js.jsx
を次のように編集します。
var MiniTodo = React.createClass({
requestMiniTodo: function (url, type, data) {
$.ajax({
url: url,
dataType: 'json',
type: type,
data: data,
success: function (result) {
this.setState(result);
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function () {
return {data: []};
},
componentDidMount: function () {
this.requestMiniTodo(this.props.url, 'GET');
},
handleTodoSubmit: function (todo) {
this.requestMiniTodo(this.props.url, 'POST', todo);
},
handleTodoChange: function (id, todo) {
this.requestMiniTodo(this.props.url + '/' + id, 'PATCH', todo);
},
handleTodoDestroy: function (id) {
this.requestMiniTodo(this.props.url + '/' + id, 'DELETE');
},
render: function () {
return (
<div className="container">
<div className="panel panel-primary">
<div className="panel-heading"><h1>Todos</h1></div>
<div className="panel-body">
<TodoForm onTodoSubmit={this.handleTodoSubmit} />
</div>
<TodoList data={this.state.data} onTodoChange={this.handleTodoChange} onTodoDestroy={this.handleTodoDestroy} />
</div>
</div>
);
}
});
var TodoForm = React.createClass({
handleSubmit: function (e) {
if (event.which !== 13) {
return;
}
e.preventDefault();
var title = React.findDOMNode(this.refs.title).value.trim();
if (!title) {
return;
}
this.props.onTodoSubmit({title: title, completed: false});
React.findDOMNode(this.refs.title).value = '';
return;
},
render: function () {
return (
<input className="form-control"
placeholder="やらなければいけないこと"
autoFocus={true}
onKeyDown={this.handleSubmit}
ref="title" />
);
}
});
var TodoList = React.createClass({
handleTodoChange: function (id, todoItem) {
this.props.onTodoChange(id, todoItem);
},
handleTodoDestroy: function (id) {
this.props.onTodoDestroy(id);
},
render: function () {
var todoItems = this.props.data.map(function (todoItem) {
return (
<TodoItem key={todoItem.id} data={todoItem} onTodoChange={this.handleTodoChange} onTodoDestroy={this.handleTodoDestroy} />
);
}, this);
return (
<ul className="list-group">
{todoItems}
</ul>
);
}
});
var TodoItem = React.createClass({
handleCompletedChange: function (e) {
e.preventDefault();
var completed = React.findDOMNode(this.refs.completed).checked;
this.props.onTodoChange(this.props.data.id, {title: this.props.data.title, completed: completed});
return;
},
handleTodoItemDestroy: function (e) {
this.props.onTodoDestroy(this.props.data.id);
},
render: function () {
return (
<li className="list-group-item">
<div className="checkbox">
<label>
<input type="checkbox"
checked={this.props.data.completed}
onChange={this.handleCompletedChange}
ref="completed"
/>{this.props.data.title}
</label>
<button type="button" className="close" aria-label="Close" onClick={this.handleTodoItemDestroy}><span aria-hidden="true">×</span></button>
</div>
</li>
);
}
});
コントローラを実装します。rails generate controller
コマンドで、コントローラのテンプレートを生成します。コントローラ名は、Todos
とします。
bundle exec rails generate controller todos
ビューは、先ほど実装した MiniTodo コンポーネントでレンダリングするように、ファイル app/views/todos/index.html.erb
を次の内容で作成します。
<%= react_component('MiniTodo', url: '/api/v1/todos') %>
ファイル config/routes.rb
を編集して、ルーティングを設定します。
Rails.application.routes.draw do
get 'hello' => 'hello#index', defaults: { format: 'json' }
namespace :api, format: 'json' do
namespace :v1 do
resources :todos, :only => [:index, :create, :update, :destroy]
end
end
root 'todos#index'
end
これで、Todo 管理ウェブアプリが完成しました。
Docker イメージの再作成
(↑クリックで拡大表示)
続いて、Docker イメージを再作成します。Docker イメージの再作成に用いる Dockerfile
は、これまでのものをそのまま使用します。
Docker イメージ名のタグ(バージョン)は、1.1.0
から 1.2.0
に変更します。
docker build -t username/mini-todo:1.2.0 .
作成した Docker イメージを Docker Hub に登録します。
docker push username/mini-todo:1.2.0
デプロイ
(↑クリックで拡大表示)
ここまでで、デプロイの準備が整いました。すでに MAGELLAN で動いている Worker をバージョンアップするデプロイを実施しましょう。
デプロイは、ウェブブラウザーでの作業となります。ウェブブラウザーの画面をステージ DefaultStage1 に切り替えて、以下の手順に沿って作業してください。
今回は、ウェブブラウザーから Worker (MAGELLAN) にアクセスするため、MAGELLAN 標準設定を変更します。
まず、Worker (MAGELLAN) に認証なしでアクセスできるように変更します。
をクリックします。
「Stage の編集」画面が表示されます。
「Authentication」フィールドの「認証なし」をチェックします。
をクリックします。
次に、Worker にサブドメインを割り当てます。
左サイドメニューから「DefaultProject1」のリンクをクリックします。
プロジェクト DefaultProject1 の画面が表示されます。
「Client Versions」タブをクリックします。
クライアントバージョンの管理画面に切り替わります。
「DefaultStage1」の行右端の
をクリックします。
「クライアントバージョンの編集」画面が表示されます。
「Domain」入力欄に、
*****-minitodo
と入力します。***** の部分は、MAGELLAN のアカウント名に読み替えてください。アカウント名は、MAGELLAN コンソール右上の
左横で確認できます。
をクリックします。
これで、ウェブブラウザーから、http://*****-minitodo.magellanic-clouds.net
の URL で、Worker にアクセスする準備が整いました。
最後に、Worker を情報を更新し、Worker を再起動します。
「DefaultStage1」のリンクをクリックします。
ステージ DefaultStage1 の管理画面が表示されます。
「Planning」タブをクリックします。
Worker 情報を作成・編集する画面が表示されます。
「Image Name」入力欄に、
username/mini-todo:1.2.0
と入力します。更新した Worker 情報を保存します。入力内容に間違いがないことを確認して、
をクリックします。
をクリックして、コンテナを再起動します。
動作確認
ウェブブラウザーで、http://youraccount-minitodo.magellanic-clouds.net/
にアクセスして、動作確認します。
おめでとうございます。
以上で終了です。ここで、Worker 開発環境は、終わらせておきましょう。ターミナルに戻り、docker exec -it worker-devenv su magellan
したターミナルすべてで、exit
コマンドを実行してください。その後、次のコマンドを実行してください。
docker stop mysql worker-devenv && docker rm mysql worker-devenv
このステップのまとめ
最後に、このステップで学んだことをまとめます。
- ウェブブラウザーから Worker にアクセスするためには、MAGELLAN 標準設定の変更が必要
- 「Stage の編集」画面で、「Authentication」を「認証なし」へ変更
- 「クライアントバージョンの編集」画面で、サブドメインを割り当てる
なお、Worker の詳しい作り方は、「MAGELLAN 用ウェブアプリケーションの作り方」で解説しています。