Upload
unicast-inc
View
956
Download
1
Embed Size (px)
Citation preview
UNICAST ・ワークショップ vol.2
Rails を使った Web サービスの作り方~ Rails の環境で Web サービスを作ってみよ
う!~
1
前回のおさらい• WebSocket– サーバからブラウザへ好きなタイミングでデータを
送信できる– Web ブラウザによって対応状況がまちまち
• Ruby on Rails– MVC アーキテクチャ– アプリに必要な枠組みは Rails が生成
• 開発が楽!
2
MVC アーキテクチャ
3
Ruby on Rails (Rails) とは?• Ruby による Web アプリケーション
向けの MVC フレームワーク• 37signals のプログラマ、 David
Heinemeier Hansson が開発• Rails を利用しているサービス– クックパッド– 食べログ– Twitter (~ 2008 )
4
準備運動: Rails で Hello world!
5
work> rails new hellowork> cd hellohello> rails generate scaffold greetinghello> rake db:migrate
<p>hello, world!</p>
hello> rails server
(1) Rails プロジェクトを新規作成する
(2) app/views/hello/index.html.erb を編集し下行で置き換える
(3) サーバを起動する
(4) ブラウザでサーバにアクセスhttp://localhost:3000/greetings
準備運動: Rails で Hello world!
6
ここまでのまとめ• アプリに必要なものは Rails が用意してくれる• railsコマンドはアプリに必要なものを生成する– モデル、ビュー、コントローラの生成– サーバの起動
• rake db:migrateコマンドでデータベースのセットアップが行われる
7
今日の目標• 実際に Web サービスを作って Web アプリ開発を
体験します• 合宿に向けて、 Rails の実践的な使い方を学びま
す
8
お題• iOS アプリレビューサイト あぷレビュ!(仮
称)– App Store からアプリのデータを取得し、レビューを
投稿・共有するサービス– App Store にもレビュー投稿機能がありますが、今回
はオリジナルのレビューシステムを Rails で作ります
9
お題• トップページ
10
お題• 検索結果のページ
11
お題• レビュー表示・投稿のページ
12
おことわり• 今回の内容は Ruby や HTML の知識が必要になる
部分が所々に出てきます• ですが尺の都合上、 Ruby や HTML についての説
明は省きます• よくわからないコードが出てきても、今回はと
りあえずそういうものなのだと思って、後で自習してください(丸投げ)
13
1.アプリの設計• 作りたいアプリの仕様をざっくりと決めます• 紙と鉛筆を使って、絵や図を描きながら考えま
しょう• 開発に関わるメンバー全員で議論しながら考え
ましょう
14
1.アプリの設計• ページフロー– ページの見た目やページ間のつながりを考えます– 主に MVC の「ビュー」の部分
15
1.アプリの設計• テーブルの設計
– アプリが使うデータについて考えます– MVC の「モデル」の部分– どんなデータを扱うのかを、分類ごとに箇条書きで書きます– モデル同士に関連があれば、それも描きこみます
16
1.アプリの設計• モデルの関連– モデルには 1 対 1 、 1 対多、多対多などの関連があり
ます– あぷレビュ!の場合、一つのアプリに複数のレ
ビューがつくと考えられるので、アプリとレビューは1 対多の関係となります
17
アプリ
レビュー レビュー ・・・
アプリ レビュー
1 0…*
1.アプリの設計• その他、開発に必要なことを色々考えておきます
– どのぐらいの期間で完成できる?• 今回は 3 時間。終わらなかったら次回にやるかも。
– 必ず実装しなくてはいけない部分は?• iTunes Store からデータを取得• アプリのデータとレビューの情報の紐づけ
– 逆に、必ずしも実装しなくてもよい部分は?• 新着レビューの表示(なくても見栄えは悪いが一応動く)
– 一番実装が難しい部分は?• iTunes Store からレコードを取得する部分?
– どんな技術や知識が必要?• Rails 、 Ruby 、 HTTP 、データベース
18
2.プロジェクトの新規作成• いよいよ実際にプログラムを書いていきます• まずはプロジェクトの作成
19
work> rails new appreview create create README.rdoc create Rakefile…中略…Using sqlite3 (1.3.6) Using uglifier (1.2.7) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
work> cd appreview
2. Gem の追加• Ruby のモジュールの単位を Gem と呼びます• たくさんのアプリやライブラリが Gem として公
開されています• 今回は App Store からアプリのデータを取得する
ために HTTPClient という Gem を使います
20
2. Gem の追加• Rails プロジェクトが使う Gem は Gemfile という
ファイルに書かれています• Gemfile の末尾に HTTPClient を追記します• ファイルの文字コードは UTF-8 を指定してくだ
さい
• 終わったら Gem をインストールします
21
…gem ‘httpclient’
appreview> bundle install
3.サーバの起動• 動作確認のためのサーバを起動します• 新しいコマンドプロンプトを開いて、以下のコ
マンドを実行します
• http://localhost:3000 にアクセスできますか?
22
appreview> rails server
4.トップページ(兼、検索ページ)を作成• 今度はトップページ(兼、検索ページ)を作り
ます• rails コマンドを使って、ページのひな形を生成
します
23
appreview> rails generate controller Home index search
4.トップページ(兼、検索ページ)を作成• 先ほどのコマンドで以下のファイルが生成され
ました– app\controllers\home_controller.rb
• トップページのコントローラ– app\views\home\index.html.erb
• トップページのビュー– app\views\home\search.html.erb
• 検索ページのビュー• 生成されたファイルを確認してみてください
24
5.ブラウザで確認• 次の URL にアクセスして、生成したコントロー
ラとビューが無事動くことを確認してみてください– http://localhost:3000/home/index– http://localhost:3000/home/search
25
6.トップページを変える• まだ http://localhost:3000 はデフォルトのままです• config\routes.rb を編集して、先ほど作成したトップページ
に移動するようにします
• デフォルトのトップページである public\index.html は削除します
• トップページは変わりましたか?26
Appreview::Application.routes.draw do get "home/index"
get "home/search"
root :to => 'home#index‘…
appreview> del public\index.html
7.トップページのビューを書く• トップページのビューを書いていきます• Rails では ERB (embedded Ruby) という形式で
ビューを書きます– ERB では <% … %> で囲った文字列が Ruby の式として解釈されます
– 例えば <%= 1+1 %> と書いた場合、ブラウザでは 2 と表示されます
– つまり、 HTML の中に Ruby のプログラムを埋め込めるわけです
27
7.トップページのビューを書く• app\views\home\index.html.erb を編集して、タイトルと
検索窓を持つトップページを実装します
• ブラウザをリロードして、出来栄えを確認しましょう• 検索窓で何か検索してみてください(おそらく Routing
Error になりますが)
28
<div id=“top”> <h1> あぷレビュ !</h1> <p class=“search_field”> <%= form_tag "/search", :method => "get" do %> <%= search_field_tag "q", " アプリを検索 " %> <%= submit_tag " 検索 ", :name => nil %> <% end %> </p></div>
8.検索ページに移動するようにする• Routing Error のままでは使い物にならないので、
config\routes.rb を編集して検索ページに飛ぶようにします
• 検索ページに飛ぶようになりましたか?
29
Appreview::Application.routes.draw do get "home/index"
get "home/search"
root :to => 'home#index‘ match ‘/search’ => ‘home#search’…
9.検索処理をコントローラに実装する• 検索ページでは、 App Store からアプリデータを
検索し、表示します• App Store には Webアプリからアクセスするた
めの専用の API が公開されています• 今回は HTTPClient で API にアクセスし、アプリ
のデータを取得します• 検索処理や DB へのアクセスといった仕事はコン
トローラの役目です• コントローラに検索処理を実装していきます
30
9.検索処理をコントローラに実装する• app\controllers\home\home_controller.rb を編集し
ます
31
def search # 検索する文字列を取得 @query = params[:q]
content = HTTPClient.new.get_content( "http://itunes.apple.com/search", "term" => @query, # 検索キーワード "country" => "jp", "entity" => "software") # JSON 形式のレスポンスを解析する json = JSON.parse(content) # 変数 @results にアプリのリストを格納する @results = json["results"]
# app/views/home/search.html.erb を表示 render :action => "search" end
10.検索ページのビューを書く• 検索処理を実装しましたが、まだビューを書い
ていないので表示できません• 変数 @results に格納した検索結果を表形式で出力するようにします
• app\views\home\search.html.erb を編集します
32
10.検索ページのビューを書く
33
<h2> 検索結果 </h2><%= form_tag "/search", :method => "get" do %> <%= search_field_tag "q", @query %> <%= submit_tag " 検索 ", :name => nil %><% end %><hr /><table class="results"> <tr> <th></th><th> タイトル </th><th> ジャンル </th><th> 開発者 </th><th> 価格 </th> </tr> <% @results.each do |record| %> <tr> <td><%= image_tag record["artworkUrl60"] %></th> <td><%= record["trackName"] %></td> <td><%= record["genres"].join(', ') %></td> <td><%= record["artistName"] %></td> <td><%= record["formattedPrice"] %></td> </tr> <% end %></table>
<hr /><%= link_to " トップ ", "/" %>
10.検索ページのビューを書く• ここまですべてがうまくいっていれば、検索窓
から自由にアプリを検索できるようになっているはずです
34
11.レビューのモデルを生成する• トップページと検索ページが完成しました• 次はレビュー機能を実装します• 投稿されたレビューや、レビューされたアプリ
の情報を保存するためのモデルを生成しましょう
35
appreview> rails generate scaffold App store_id:integer title:string developer:string price:decimalappreview> rails generate scaffold Review name:string comment:string rate:integer app:referencesappreview> rake db:migrate
11.レビューのモデルを生成する• 以下のファイルは生成されたでしょうか– app\models\app.rb– app\models\review.rb– app\controllers\apps_controller.rb– app\controllers\reviews_controller.rb– app\views\apps\show.html.erb
36
12. 1 対多の関連を設定する• さて、最初に設計したモデルでは、アプリとレ
ビューは 1 対多の関連を持っているのでした• 先ほどのレビューのモデルを生成するコマンド
で、 app:references と指定しているのは「 Review
は App と関連している」ということを Rails に伝えるためだったのです
• 次に「 App は複数の Review と関連している」ということを Rails に伝えるため、アプリのモデルを編集します
37
12. 1 対多の関連を設定する• app\models\app.rb を開いて、以下のように編集
します
• :reviewではなく :reviewsです• これで 1 対多の関連が構築されました
38
class App < ActiveRecord::Base has_many :reviews attr_accessible :developer, :price, :store_id, :titleend
13.レビューページのビューを作成する• レビューを投稿・表示するページのビューを作成
します
• app\views\apps\show.html.erb を編集します• 長いので、入力が面倒な人はコピペで構いませ
ん
39
13.レビューページのビューを作成する
40
<h2><%= @app.title %> - レビュー </h2><p id="notice"> <%= notice %></p><hr /><table class="info"> <tr><th> 開発者 </th><td><%= @app.developer %></td><th>価格 </th><td><%= @app.price %>円 </td></tr></table><table class="reviews"> <tr><th> お名前 </th><th> レート </th><th> レビュー </th></tr> <% @app.reviews.each do |r| %> <tr><td><%= r.name %></td><td><%= "★" * r.rate %></td><td><%= r.comment %></td></tr> <% end %></table><hr /><h3> レビューを書く !</h3> <%= form_for([@app.reviews.build]) do |f| %> <%= f.hidden_field :app_id, value: @app.id %> <div class="field"> <%= f.label " お名前 " %><br /> <%= f.text_field :name %> </div> <div class="field"> <%= f.label " レート " %><br /> <%= f.select :rate, (0..5).to_a.collect {|i| ["★"*i, i]} %> </div> <div class="field"> <%= f.label " レビュー " %><br /> <%= f.text_area :comment %> </div> <div class="actions"> <%= f.submit "投稿 " %> </div><% end %><hr /><%= link_to " トップ ", "/" %>
14.レビューページを新規作成する処理を書く• レビューはアプリに関連付けられて投稿されま
す• レビューを投稿するためには、あらかじめアプ
リの情報がデータベースに登録されている必要があります
• 検索結果のページからアプリをクリックしたとき、そのアプリが DB に登録されていなければDB にアプリ情報を登録する処理を書きます
41
14.レビューページを新規作成する処理を書く• app\controllers\apps_controller.rb を編集
し、 index メソッドを以下で置き換えます
42
class AppsController < ApplicationController # GET /apps # GET /apps.json def index if params[:store_id] app = App.where("store_id = :store_id", params).first # もしアプリの情報が DB になければ新規作成する unless app app = App.new app.store_id = params[:store_id].to_i app.title = params[:title] app.developer = params[:developer] app.price = params[:price].to_f app.save end # レビューのページに飛ぶ redirect_to action: "show", id: app.id end end
15.レビューページに飛ぶリンクを追加する• これでレビューページを表示するために必要な
ものが揃いました• 次に、レビューページに飛ぶためのリンクを検
索結果のページに追加しましょう
43
15.レビューページに飛ぶリンクを追加する• app\views\home\search.html.erb を編集します• アプリタイトルの所にレビューページへのリン
クが張られるように、以下のように修正します
44
<% @results.each do |record| %> <tr> <td><%= image_tag record["artworkUrl60"] %> <td>
<%= link_to record["trackName"], apps_path( store_id: record["trackId"],
title: record["trackName"], developer: record["artistName"], price: record["price"]) %> </td> <td><%= record["genres"].join(', ') %></td> <td><%= record["artistName"] %></td> <td><%= record["formattedPrice"] %></td> </tr> <% end %>
15.レビューページに飛ぶリンクを追加する• これで検索結果のページからレビューのページ
に行けるようになりました• ブラウザで動作を確認してみてください
45
16.投稿したアプリのページに戻るようにする• さて、いよいよ最後です• レビューの投稿ボタンを押すと、 Listing reviews
と表示されるページに飛ぶと思います• これをレビューの投稿時に、投稿したアプリの
ページに戻るようにします• これは Review のコントローラが処理しています
46
16.レビューを投稿できるようにする• app\controllers\reviews_controller.rb の create メソッドを以下のように編集します
47
def create @review = Review.new(params[:review])
respond_to do |format| if @review.save format.html { redirect_to App.find(@review.app_id), notice: 'Review was successfully created.' } format.json { render json: @review, status: :created, location: @review } else format.html { render action: "new" } format.json { render json: @review.errors, status: :unprocessable_entity } end end end
16.レビューを投稿できるようにする• @review.app_id は Review オブジェクトの属性
app_id にアクセスするという意味です• デフォルトでは属性 app_id にアクセスするため
の設定が Review オブジェクトにされていないので、これを修正します
• app\models\review.rb を編集します
48
class Review < ActiveRecord::Base belongs_to :app attr_accessible :comment, :name, :rate, :app_idend
16.レビューを投稿できるようにする• これでレビューが投稿できるようになりまし
た!• すべてがうまくいっているか、ブラウザで確認
してみてください
49
17.さらに拡張• これで一通りの機能が揃いました• しかし、まだ課題はあります– 見た目がまだ不細工です
• HTML やスタイルシートを工夫して見栄えをよくしてみましょう
– レビューが削除ができない• コントローラに削除の処理を追加してみましょう
– 機能が少なくて、 Web サービスとしてはまだまだしょぼい
• 改善点を見つけて、取り組んでみましょう
50
スキルアップのために• Web アプリ開発は非常に広範な知識を要求され
る分野です• 今回の課題だけでも、 Rails 、 Ruby 、 HTTP 、
データベース、 HTML といった知識が必要になりました
• Web アプリ開発を習得するためには、たくさん書籍を読んで、実際に手を動かしてみるほかありません
51
参考書籍• 幸い、 Ruby や Rails は非常に参考になる書籍が
出ています– たのしい Ruby 第 3版
• 高橋征義、後藤裕蔵(著)、まつもとゆきひろ(監修)• 出版:ソフトバンククリエイティブ
– Rails によるアジャイル Web アプリケーション開発第4 版• Sam Ruby, et al.( 著 ), 前田 修吾 ( 翻訳 ) • 出版:オーム社
• 合宿までの間、図書館で借りるなどして読んでおくこと良いと思います
52
まとめ• Rails についておさらいしました– MVC アーキテクチャ– 自動生成で簡単に作れる
• Rails で Web サービスを作りました– アプリをざっくり設計し、図に起こしました– 設計をもとに Rails でモデル、ビュー、コントローラ
を生成し、中身を実装しました– App Store の検索 API を使って、アプリのレビューサイ
トを構築しました
53
おわり
54