2011年11月16日水曜日
Railsを使ったアプリケーション開発 (その4 応用編 認証機能の追加)
Railsを使ったアプリケーション開発 (その1 事前準備編)
Railsを使ったアプリケーション開発 (その2 基礎編)
Railsを使ったアプリケーション開発 (その3 応用編)
3回に渡ってRailsを使ってきた。4回目は、認証機能をフィルタを利用して実装させる。
一からログインユーザを管理するテーブルを作るのは手間なので、その3にて作成済みのusersテーブル(userモデル)を利用する。
◆ フィルタを利用した認証機能
アクションの前に処理を実行させるbefore_filterを利用する。ApplicationControllerはすべてのコントローラの基底クラスになっているのでどのアクションにも事前に適用されることとなる。
# vi ./app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :check_logined
private
def check_logined
if session[:user] then
begin
@user = User.find(session[:user])
rescue ActiveRecord::RecordNotFound
reset_session
end
end
unless @user
flash[:referer] = request.fullpath
redirect_to :controller => 'login', :action => 'index'
end
end
end
protect_from_forgeryメソッドというのが気になったかもしれない。目的はCSRF対策であり、以下で呼び出される。
# cat app/views/layouts/application.html.erb
<%= csrf_meta_tags %>
Railsでは自動でCSRF対策をしてくれるので3点だけ気に留めておけばよい。
● HTTP GETを使ってデータ操作は行わない
● データ操作のリクエストはビューヘルパー(form_for、form_tag、link_to)を利用する
● レイアウト変更時はcsrf_meta_tagsメソッドを呼び出す
さてこれで前回作った検索サイトにでもアクセスしてみたとする。
※実際にはまだアクセスはできない
http://x.x.x.x/store/search
初回のアクセスでは当然unless文をたどることになるので、
ログインページへとリダイレクトされるはずだ。
http://x.x.x.x/login/index
認証が通った場合は、リクエストしたページへ行く必要があるため、フラッシュ(flash)を使ってそのページを覚えさせておく。フラッシュとはいわゆるセッションなのだが、次のリクエスト先で自動で削除されるためセッションの管理の手間が省けるメリットがある。
テンプレート変数を使うことはできない。テンプレート変数は現在のコントローラでのアクションとビューのテンプレート間でしか共有できないからだ。renderと異なり、redirect_toはリダイレクトによる処理の委譲を意味するものである。クライアントにリダイレクト先URLを返却し、クライアントは再度そのURLにリクエストをあげるという動きを考えれば理解が得られるだろう。よってこのようなページまたぎには、一時的な変数としてフラッシュを使うのである。
ではこのlogin/indexページも作成しよう。
いつもの通りコントローラとビューを作っていけばいい。
ここでは先にビューを見た方が分かりやすいだろうか。
# vi app/views/login/index.html.erb
<p style="color: Red"><%= @error %></p>
<%= form_tag :action => 'auth' do %>
<div class="field">
<label>USER NAME:<br />
<%= text_field_tag(:name, '', { :size => 20 }) %></label>
</div>
<div class="field">
<label>PASSWORD:<br />
<%= password_field_tag(:password, '', { :size => 20 }) %></label>
</div>
<%= hidden_field_tag :referer, flash[:referer] %>
<%= submit_tag 'login' %>
<% end %>
indexページのコントローラは特に今回のサンプルでは不要であろう。formタグで指定したauthページはコントローラから別URLへリダイレクトさせるためビューは不要である。
また、このauthページは当然認証は不要であるためskip_before_filterを利用している。
# vi app/controllers/login_controller.rb
class LoginController < ApplicationController
skip_before_filter :check_logined
def index
特に今回のサンプルでは不要
end
def auth
user = User.authenticate(params[:name], params[:password])
if user then
session[:user] = user.id
redirect_to params[:referer]
else
flash.now[:referer] = params[:referer]
@error = 'username / password error'
render 'index'
end
end
def logout
reset_session
redirect_to '/'
end
end
submitフォームからのPOST情報はparamsメソッドで受け取れる。paramsメソッドではURLの末尾に付与される情報や、ルートで定義されたパラメータ(例 /books/1 の1など)も取得できる。
ユーザ情報を引けなかった場合はelse文をたどるわけだが、そこでflash.nowを利用している。テンプレート変数(@~)を使わないのはなぜだろうか。それは"./app/views/login/index.html.erb"内ではhiddenタグ内にflashの結果を埋め込んでいるためである。flash.nowにしているのは、次のリクエストまでフラッシュを残しておく必要がないからだ。
ログアウト処理させるならlogoutメソッドを呼べばよい。
最後にUserモデルのメソッドをモデル内で定義しておく。
# vi app/models/user.rb
class User < ActiveRecord::Base
def self.authenticate(name, password)
where(:name => name,
:password => password).first
#:password => Digest::SHA1.hexdigest(password)).first
end
end
以上
2011年11月15日火曜日
Railsを使ったアプリケーション開発 (その3 応用編)
Railsを使ったアプリケーション開発 (その1 事前準備編)、
Railsを使ったアプリケーション開発 (その2 基礎編)
ときて、いよいよ3回目である。
いよいよ書籍を管理するアプリケーションを作る。
手動でコントローラ、ビュー、モデルを作成してきたがもっと楽な手段がある。
Scaffolding機能を使う方法である。コマンド一発で、特定のテーブルをCreate、Read、Update、Delete操作できる、簡易アプリケーションが作れてしまう。
この機能を利用して書籍管理アプリケーションを作ってみる。
◆ テーブルの設計
実体と属性
()はrailsが自動で作成する。
赤は主キー、青は非主キーである。
*が外部キーを表す。
books
(id) title price (created_at) (updated_at)
users
(id) name password (created_at) (updated_at)
authors
(id) name (created_at) (updated_at)
reviews
(id) bookd_id* user_id* body (created_at) (updated_at)
books_authors
book_id* author_id*
ER図もどき
books 1 - N reviews N - 1 users
1
|
N
author_books
N
|
1
authors
◆ Scaffoldingを利用して関連ファイルを一括作成
今はここにいる。
# pwd
/var/www/rails/bookapp
モデルクラス名は単数なので注意を。複数形にするのはテーブルだけである。
# rails generate scaffold book title:string price:integer
# rails generate scaffold user name:string password:string
# rails generate scaffold author name:string
# rails generate scaffold review book:references user:references body:text
# rails generate model authors_book book:references author:references
author_booksだけscaffoldで作らなかった。純粋な中間テーブルをCRUDに従った操作をする必要はないと判断したためである。もちろん作ってもかまわない。
◆ マイグレーションファイルによるテーブルの作成
自動でマイグレーションファイルはできているが、主キー列、created_at列、updated_at列が不要な中間テーブルの作成前には一部編集が必要である。主キーを無効化し、かつタイムスタンプ列を削除する。
# vi db/migrate/20111113040505_create_author_books.rb
def change
create_table :author_books, :id=>false do |t|
t.references :book
t.references :author
t.timestamps ←削除
end
add_index :author_books, :book_id
add_index :author_books, :author_id
end
テーブルを作成する。
# rails db:migrate RAILS_ENV=development
◆ テストデータの流し込み
自動でテストデータが作られている。流し入れるデータを変えたければymlファイルを編集すればよい。
# vi test/fixtures/books.yml
book1:
title: book1
price: 1000
book2:
title: book2
price: 2000
book3:
title: book3
price: 3000
上記のように記載していくと手間がかかるためブロックを使った式をymlファイルに記載してもよい。
<% 1.upto(3) do |n| %>
book<%= n %>:
title: book<%= n %>
price: <%= n * 1000 %>
<% end %>
# vi test/fixtures/users.yml
<% 1.upto(3) do |n| %>
user<%= n %>:
name: name<%= n %>
password: password<%= n %>
<% end %>
# vi test/fixtures/authors.yml
<% 1.upto(3) do |n| %>
author<%= n %>:
name: name<%= n %>
<% end %>
reviwesテーブルはカラムにbookd_idとuser_idをもち、それぞれbooksテーブル、usersテーブルの外部キーになっているはずである。しかしbook_id、user_idにidを入れて参照元のテーブルと紐づけるのは手間である。そこでラベル名で参照先を識別させることもできる。
# vi test/fixtures/author_books.yml
one:
book: book1
author: author2
two:
book: book3
author: author1
上と同じく、book_id、user_idは使わずラベル名を利用する。
# vi test/fixtures/reviews.yml
one:
book: book1
user: user2
body: fantastic
two:
book: book2
user: user3
body: interesting
ymlの試験データを元にデータをテーブルへ流し込む。
# rails db:fixtures:load FIXTURES=books RAILS_ENV=development
# rails db:fixtures:load FIXTURES=users RAILS_ENV=development
# rails db:fixtures:load FIXTURES=authors RAILS_ENV=development
# rails db:fixtures:load FIXTURES=reviews RAILS_ENV=development
# rails db:fixtures:load FIXTURES=author_books RAILS_ENV=development
同じコマンドを2回打っても追記はされない。ymlファイルに記載されているものだけが挿入される。既に存在している行があってもymlになければその行は削除される。
データベースを初期化するにはこうである。
# rails db:reset
◆ ルーティングの作成
ルーティングも自動で入っている。
# cat config/routes.rb
(略)
resources :reviews
resources :authors
resources :users
resources :books
(略)
# rails routes
ヘルパー名 HTTPメソッド URLパターン ルートパラメータ
(略)
books GET /books(.:format) {:action=>"index", :controller=>"books"}
POST /books(.:format) {:action=>"create", :controller=>"books"}
new_book GET /books/new(.:format) {:action=>"new", :controller=>"books"}
edit_book GET /books/:id/edit(.:format) {:action=>"edit", :controller=>"books"}
book GET /books/:id(.:format) {:action=>"show", :controller=>"books"}
PUT /books/:id(.:format) {:action=>"update", :controller=>"books"}
DELETE /books/:id(.:format) {:action=>"destroy", :controller=>"books"}
(略)
ヘルパーとはテンプレートファイルを記述する際に役立つメソッドの総称である。
パスヘルパー 得られるパス
books_path /books/
book_path(id) /books/:id
new_book_path /books/new
edit_book_path(id) /books/:id/edit
例
<%= link_to 'Edit', edit_book_path(book) %>
<%= link_to 'New', new_book_path(book) %>
XXX_path 部分を XXX_url に変えると相対パスから、絶対パスになる。
さて、RESTfulなインターフェースになっていることに気がつくだろうか。RESTfulであるとは一意なURLに対して、CRUD(Create、Read、Update、Delete)を使ってアクセスできるということである。CRUDをHTTPプロトコルにあてはめると、POST、GET、PUT、DELETEになる。URLを一意にすることでインターフェースを統一し、プロトコルにしたがってルートパラメータでリソースを制御するのである。
◆ 確認
テーブルを作成し、テストデータを流し込んだので以下にアクセスして確認してみる。
Create、Read、Update、Delete操作ができるので触ってみてほしい。
http://x.x.x.x/books
http://x.x.x.x/users
http://x.x.x.x/authors
http://x.x.x.x/reviews
ついでに検証機能もいれておこう。
◆ モデルファイルの編集(検証機能の設定)
bookモデルに検証機能を入れる。
タイトルは必須、また長さは1~100。
価格はintegerのみで価格は100000以下。
# vi app/models/book.rb
validates :title,
:presence => true,
:length => { :minimum => 1, :maximum => 100 }
validates :price,
:numericality => { :only_integer => true, :less_than => 100000 }
再度アクセスして、書籍を新規に登録してみよう。
http://x.x.x.x/books
検証機能に違反する操作を行うとエラーが出るはずである。
これはどうやってエラーを表示させているのであろうか。
# cat app/views/books/new.html.erb
<%= render 'form' %>
部分テンプレートになっている
# cat app/views/books/_form.html.erb
<% if @book.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@book.errors.count, "error") %> prohibited this book from being saved:</h2>
<ul>
<% @book.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
CSSを変えたければ以下のファイルのfield_with_errorsを編集すればよい。
# cat ./app/assets/stylesheets/scaffolds.css.scss
.field_with_errors {
(略)
}
最後に、複数のオブジェクトモデル(リレーショナルテーブル)を作ったので
それらを連携させたアプリケーションを作成する。
http://x.x.x.x/store/search
にアクセスして書籍を検索できるサイトを作る。
◆ モデルファイルの編集(アソシエーションの設定)
"◆ テーブルの設計"で作成したER図を見ながら考える。
再掲
books 1 - N reviews N - 1 users
1
|
N
author_books
N
|
1
authors
# vi app/models/book.rb ※下記コードを挿入
has_many :authors
has_many : author_books
has_many :authors, through: :author_books
# vi app/models/user.rb ※下記コードを挿入
has_many :reviews
has_many :books, through: reviews
# vi app/models/author.rb ※下記コードを挿入
has_many :author_books
has_many :books
# vi app/models/review.rb ※下記コードを挿入
# booksテーブルとusersテーブルのM:Nひもづけ用中間テーブル
belongs_to :book
belongs_to :user
純粋な中間テーブル用のモデルは不要である
# rm app/models/books_author.rb
◆ コントローラとビューの作成
# rails generate controller store
# vi app/views/store/search.html.erb
<%= form_tag :action => 'scan' do %>
<div class="field">
<%= label_tag 'title', 'book title:' %><br />
<%= text_field_tag 'title' %>
</div>
<%= submit_tag 'search' %>
<% end %>
# vi app/controllers/store_controller.rb ※下記コードを挿入
def scan
@books = Book.where('title = ?', params[:title])
render 'list'
end
<% @books.each do |book| %>
<h1>TITLE : <%= book.title %></h1>
<hr />
<ul>
<li>PRICE : <%= book.price %></li>
<% book.authors.each do |author| %>
<li>AUTHOR : <%= author.name %> </li>
<% end %>
</ul>
<h1>REVIEW</h1>
<hr />
<ul>
<% book.reviews.each do |review| %>
<li><%= review.body %>(<%= review.updated_at %>)</li>
<% end %>
</ul>
<% end %>
◆ ルーティングの編集
"http://localhost/bookapp/store/search"としてアクセスさせたい。RESTfulインターフェースにはsearch、scan、listのアクションはないので、自前で用意する。
# vi config/routes.rb
resources :store do
collection do
get 'search'
post 'scan'
get 'list'
end
end
# rails routes
search_store_index GET /store/search(.:format {:action=>"search", :controller=>"store"}
scan_store_index POST /store/scan(.:format) {:action=>"scan", :controller=>"store"}
list_store_index GET /store/list(.:format) {:action=>"list", :controller=>"store"}
collectionは複数のオブジェクトを扱うが、単一のオブジェクト、例えば、GET時に、/store/:id/hoge のようなルーティングを作りたければ、memberブロックを使う。
member :store do
member do
get 'hoge'
end
end
◆ サービス確認
書籍名に"book1"などを入れて検索結果が出てくれば成功である。
http://x.x.x.x/store/search
Next ⇒ Railsを使ったアプリケーション開発 (その4 応用編 認証機能の追加)
2011年11月14日月曜日
Railsを使ったアプリケーション開発 (その2 基礎編)
書籍を管理するアプリケーションを作ることを目的とする。
Railsを使ったアプリケーション開発 (その1 事前準備編)までは終わっているものとする。
◆ コントローラの作成
これからはすべてbookappディレクトリ配下で作業を行う。
# cd /var/www/rails/bookapp
コントローラを作る。最初なのでコントローラ名はfirstとする。
複数のアクション(メソッド)をまとめたものがコントローラと考えていい。
# rails generate controller first
generateをdestroyにするとコントローラを破棄できる。
以下のファイルは既にできている。一部を修正するだけでよい。
# vi app/controllers/first_controller.rb
class FirstController < ApplicationController
def index
@msg = 'hello world!!'
end
end
◆ ビューの作成
# vi app/views/first/index.html.erb
<div id='main'>
<%= @msg -%>
</div>
ハイフン(-)を付与すると、後方のスペースや改行を除去できる。
<html>や<body>はレイアウト側で作られているため、
ビューのテンプレートに記載する必要はない。
ディフォルトのレイアウトとして次が使われる
# cat ./app/views/layouts/application.html.erb
<html>
<head>
(略)
<%= yield %> ← ここに埋め込まれる
(略)
</body>
</html>
レイアウトを変える場合はコントローラ内のアクションメソッドで指定する。
"app/views/layouts/layout.html.erb"が呼び出される。もちろん別テンプレートを使う場合は、自分で作成する必要がある。
def index
render :layout => 'layout'
end
◆ ルーティングの作成
:controllerと:actionはコントローラとその中のアクションメソッドであり、:idはアクションメソッドに渡されるパラメータである。丸括弧部分は省略可能である。
# vi config/routes.rb
get ':controller(/:action(/:id(.:format)))'
# rails routes
◆ 確認
http://x.x.x.x/first/index へブラウザからアクセスする。
hello world!!
と表示されれば成功である。
続いてモデルの開発を行うが、その前に備忘録。
◆ 備忘録
● ログについて
うまく表示されない場合はログを参考にエラー原因を特定する。
# tail -f log/development.log
● コントローラとビューについて
コントローラのアクションメソッドとビューのテンプレートを共に用意しなければならないのであろうか。
コントローラのアクションメソッド ビューのテンプレート
(1) あり あり
(2) なし あり
(3) あり なし
(1)
これは上で作った通り、コントローラとビューを用意した場合である。リクエストの起点としてコントローラクラスのアクションメソッドが実行された後、対応するビューのテンプレートが検索され実行される。
(2)
アクションメソッドが存在しない場合、テンプレートファイルを直接見に行く。つまりビューだけでも問題ない。ただし、MVC(Model、View、Controller)は役割を分けることを目的としているため、意味もなくビューだけでアプリを完遂させるべきでないことは言うまでもない。
(3)
アクションメソッドが存在し、テンプレートファイルがない場合はエラーになる。ただし、次の場合を除く。
a. テキストスクリプトを出力する場合
# vi ./app/controllers/first_controller.rb
class FirstController < ApplicationController
def index
render :text => 'hello world!!'
end
end
b. アクションメソッド内で、リダイレクトURIを指定している場合
# cat ./app/controllers/first_controller.rb
class FirstController < ApplicationController
def index
redirect_to 'http://example.com'
end
end
c. アクションメソッド内で、別のアクションメソッドを呼び出している場合
コントローラのアクションメソッドではなく、
ビューのテンプレートファイルが読み出されることに注意が必要である。
# vi ./app/controllers/first_controller.rb
class FirstController < ApplicationController
def index
@msg = 'hello world!!'
render :action => 'index2'
end
end
何度も言うが、actionとなっているが、ビューのテンプレートが読み出される。つまり、ビューのテンプレート"./app/views/first/index2.html.erb"が必要である。ディフォルトの"./app/views/first/index.html.erb"ビューテンプレートではなく、renderで指定したテンプレートを使う、とう意味である。renderの意味がレンダリングであることを考えれば混乱しないだろう。
ちなみに、HTMLの<form>タグではaction属性で、送信先プログラムのURIを指定できる。それは、普通にそのURIへの処理になる。あたりまえだが、Railsのアクションとは何も関係ない。
Rails的にはURIの処理過程で、コントローラのアクションメソッド、そしてビューのテンプレートファイルが読み出されるだけである。
● renderとは
renderの話が出たのでrenderの機能をまとめておく。描画するためのrendering処理であることを考えれば統一的な理解ができる。
render
・コントローラ内メソッドのからのビューのテンプレートの呼び出し
(1)の話である。
・コントローラ内メソッドでのテキストスクリプトの出力
(3)-a の話である
・ビューのテンプレートからの部分テンプレート呼び出し
ビューのテンプレートからでもrenderは使える。
● 部分テンプレートとは
部分テンプレートの話が出たのでそのことにも触れておく。
HTMLのヘッダやフッタとして使うテンプレートは異なるが、断片的な内容は同じである場合、コードを重複して書くことを避けるため、部分テンプレートを使う。
# vi ./app/views/first/index.html.erb
<div id='main'>
<%= render :partial => 'first/partial_form %>
</div>
:partialはなくてもよい
# vi ./app/views/first/_partial_form.html.erb
<div id='sub'>
<%= @msg %>
</div>
部分テンプレートファイル名の前につく'_'は必須である。これが部分テンプレートの宣言になる。
さて、話を戻そう。
◆ モデルクラスの作成
モデルクラスを作成する。
SQLなどのデータベースでのリレーショナルモデルをアプリケーション側のオブジェクトモデルにO/R(Object/Relational)マッパーで橋渡しを行うことが目的である。
bookapp_developmentデータベースは既に作り終えている。
ある製品を管理するテーブルを作る。
実体と属性は次とする。主キー属性に別色をつけている。
products
id name price sale
SQL的に表現すれば、products(製品群)テーブルにid、name(製品名)、price(価格)、sale(仕入れ日)のカラムがある。実際に製品を管理するには不十分な内容だが練習なのでこの程度でよしとしている。
では、モデルクラスを作る。
主キーとなるID、レコードの新規作成時用のcreated_at、レコードの更新日時のupdated_atは自動で作成されるためコマンド内に含める必要はない。
# rails generate model product name:string price:integer sale:date
以下のファイルができる。
db/migrate/20111113031409_create_products.rb
app/models/product.rb
test/unit/product_test.rb
test/fixtures/products.yml
モデルとその関係ファイルを破棄する手順も残しておく。
# rails destroy model product
◆ マイグレーションファイルによるテーブルの作成
"db/migrate/20111113031409_create_products.rb"というファイルを元にマイグレーションという機能を利用してテーブルを作成する。productsというテーブルができる。テーブル名が複数形なのは、テーブルの各行(モデルクラス的に表現すればオブジェクト)は
単数であり、テーブルはその集合だからである。複数形にするのはテーブルだけである。
# rails db:migrate RAILS_ENV=development
別のデータベースを使う場合はオプションを変更する。
RAILS_ENV=test
RAILS_ENV=production
◆ テストデータの流し込み
テーブル内は空なので、"test/fixtures/products.yml"という自動で作成されるフィックスチャを元にテストデータを流し込んでおく。中を見ればわかるが2つの行(2つのオブジェクト)が投入される。流し入れるデータを変えたければymlファイルを編集すればよい。
# rails db:fixtures:load FIXTURES=products RAILS_ENV=development
フィックスチャ以外にも、シードファイルを使ってデータを入れることもできる。
# vi ./db/seeds.rb
Product.create(:name => 'MyString3', :price => 3, :sale => '2011-11-11 09:00:00')
# rails db:seed
◆ コントローラとビューの再作成
モデルも作ったのでそれを利用したコントローラとビューを作成する。
# vi app/controllers/first_controller.rb
class FirstController < ApplicationController
def show
@products = Product.all
end
end
# vi app/views/first/show.html.erb
<table border="1">
<tr>
<th>NAME</th><th>PRICE</th><th>SALE</th>
</tr>
<% @products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= product.price %></td>
<td><%= product.sale %></td>
</tr>
<% end %>
</table>
◆ サービス確認
ビューで定義したテーブルが表示できれば成功である。
http://x.x.x.x/first/show
Next ⇒ Railsを使ったアプリケーション開発 (その3 応用編)
2011年11月13日日曜日
Railsを使ったアプリケーション開発 (その1 事前準備編)
Rails4を利用して書籍を管理するアプリケーションを作ることを目的とする。
◆ Ruby on Railsのインストール
# yum install ruby ruby-devel
# gem install rails
◆ Apacheのインストール
# yum install httpd httpd-devel
◆ SQLのインストール
● SQLliteを使う場合(今回は利用しない。インストールだけ)
# yum install sqlite sqlite-devel
● MySQLを使う場合
# yum install mysql mysql-server mysql-devel
◆ バージョン確認
# ruby -v
# rails -v
# httpd -v
# sqlite3 -version
# mysql --version
◆ Apacheの設定
Apacheに組み込むRailsアプリケーション実行モジュール(Passenger)をインストールしておく。
● Passengerのインストール
# gem install passenger
● Apacheモジュールとしてインクルード
# passenger-install-apache2-module
インクルードが成功するとApacheの設定ファイルに記載するコードが表示される。
LoadModule passenger_module /usr/local/share/gems/gems/passenger-5.0.7/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/share/gems/gems/passenger-5.0.7
PassengerDefaultRuby /usr/bin/ruby
</IfModule>
<VirtualHost *:80>
ServerName www.yourhost.com
# !!! Be sure to point DocumentRoot to 'public'!
DocumentRoot /somewhere/public
<Directory /somewhere/public>
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options -MultiViews
# Uncomment this if you're on Apache >= 2.4:
#Require all granted
</Directory>
</VirtualHost>
● Apacheの設定
# vi /etc/httpd/conf.d/passenger.conf
# LoadModule、PassengerRoot、PassengerRubyは上記をそのままコピーする。
LoadModule passenger_module /usr/local/share/gems/gems/passenger-5.0.7/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/share/gems/gems/passenger-5.0.7
PassengerDefaultRuby /usr/bin/ruby
</IfModule>
# 任意だがPassengerが追加するHTTPヘッダを削除するための設定をいててもよい。
Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"
# こちらも任意だが必要に応じてPassengerのチューニングのための設定を追加しておく。
# ※詳しくは Phusion Passenger users guide
PassengerMaxPoolSize 20
PassengerMaxInstancesPerApp 4
PassengerPoolIdleTime 3600
PassengerHighPerformance on
PassengerStatThrottleRate 10
PassengerSpawnMethod smart
RailsAppSpawnerIdleTime 86400
PassengerMaxPreloaderIdleTime 0
DocumentRootの指定先フォルダは後程作成する(そのためまだhttpdは起動しない)。
RailsEnvはdevelopment(開発)、test(試験)、production(本番)を指定できる。Railsの環境は3つを使い分けられるが、さしあたりdevelopmentでいいだろう。
RailsEnv development
<VirtualHost 192.0.2.1:80>
ServerName bookapp.example.com
DocumentRoot "/var/www/rails/bookapp/public"
<Directory /var/www/rails/bookapp/public>
AllowOverride all
Options -MultiViews
</Directory>
</VirtualHost>
◆ アプリケーションの作成
書籍を管理するアプリケーションを作成していくとは述べたとおりである。
/var/www/rails/配下に、bookappというアプリケーションを新規に作成する。
mysqldをここで立ち上げておく。
# systemctl restart mysqld.service
# mysqladmin -u root password "***"
DocumentRootで指定したディレクトリを作成する。
# mkdir -p /var/www/rails/
Passengerはroot権限でRailsアプリケーションを動かせない仕様になっているので、オーナーを変更しておく。
# chown -R apache.apache /var/www/rails/
# cd /var/www/rails/
ディフォルトで利用するSQLはsqliteなのだが、今回はmysqlを利用することにしよう。そのため'-d'オプションでmysqlを付与している。
# rails new bookapp -d mysql
# cd bookapp
dbアクセス用のパスワードを記載するぐらいで、ディフォルトで使える。
# vi ./config/database.yml
〜snip〜
username: root
password: ***
〜snip〜
database.ymlファイルに基づいてデータベースを作成する。development、test、production用の3つができるはずである。どのデータベースを使うかは先に書いた通り、passenger.confのRailsEnvで指定する。
# rails db:create
個別に指定もできる。
# rails db:create RAILS_ENV=production
createをdropにするとデータベースを削除できる。
dbをのぞいて見る。
# rails dbconsole
これは下と同じである。
# mysql -u root
> show databases;
+---------------------+
| Database |
+---------------------+
| bookapp_development |
+---------------------+
確かにできている。
(補足1)
今回作成するのアプリケーションで必要となるgemは同フォルダのGemfileで定義されている。bundlerと呼ばれるアプリケーションごとのパッケージ管理システムにより、アプリケーションごとにgemを管理できる。
パッケージ管理の一般的な利用例をまず見てみる。
$ vi test.rb
require 'hogepiyo'
$ vi Gemfile
source 'https://rubygems.org'
gem 'hogepiyo'
$ bundle install --path=vendor/bundle
$ ls vendor/bundle/ruby/gems/hogepiyo-x.x.x/
Gemfileを修正した場合は、bundleコマンドで読み直しさせること。
$ bundle update
実行する。
$ bundle exec ruby test.rb
イメージがついただろう。
アプリケーションを実行するrailsのバージョンを指定することもできる。
$ vi Gemfile
gem 'rails', '3,2,13'
◆ 確認
httpdを起動させる。
# systemctl restart httpd.service
ブラウザからアクセスして確認する。
http://x.x.x.x/
DocumentRootで指定した、/var/www/rails/bookapp/public 配下のindex.htmlが読み込まれる。
"Welcome aboard" と出ていれば成功である。"About your application's environment" をクリックしアプリケーション環境に問題ないかも確認しておこう。
ここからコントローラ、ビュー、モデルと作成していくのだが、それはまた次回の
Railsを使ったアプリケーション開発 (その2 基礎編)で。
◆ Ruby on Railsのインストール
# yum install ruby ruby-devel
# gem install rails
◆ Apacheのインストール
# yum install httpd httpd-devel
◆ SQLのインストール
● SQLliteを使う場合(今回は利用しない。インストールだけ)
# yum install sqlite sqlite-devel
● MySQLを使う場合
# yum install mysql mysql-server mysql-devel
◆ バージョン確認
# ruby -v
# rails -v
# httpd -v
# sqlite3 -version
# mysql --version
◆ Apacheの設定
Apacheに組み込むRailsアプリケーション実行モジュール(Passenger)をインストールしておく。
● Passengerのインストール
# gem install passenger
● Apacheモジュールとしてインクルード
# passenger-install-apache2-module
インクルードが成功するとApacheの設定ファイルに記載するコードが表示される。
LoadModule passenger_module /usr/local/share/gems/gems/passenger-5.0.7/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/share/gems/gems/passenger-5.0.7
PassengerDefaultRuby /usr/bin/ruby
</IfModule>
<VirtualHost *:80>
ServerName www.yourhost.com
# !!! Be sure to point DocumentRoot to 'public'!
DocumentRoot /somewhere/public
<Directory /somewhere/public>
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options -MultiViews
# Uncomment this if you're on Apache >= 2.4:
#Require all granted
</Directory>
</VirtualHost>
● Apacheの設定
# vi /etc/httpd/conf.d/passenger.conf
# LoadModule、PassengerRoot、PassengerRubyは上記をそのままコピーする。
LoadModule passenger_module /usr/local/share/gems/gems/passenger-5.0.7/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/share/gems/gems/passenger-5.0.7
PassengerDefaultRuby /usr/bin/ruby
</IfModule>
# 任意だがPassengerが追加するHTTPヘッダを削除するための設定をいててもよい。
Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"
# こちらも任意だが必要に応じてPassengerのチューニングのための設定を追加しておく。
# ※詳しくは Phusion Passenger users guide
PassengerMaxPoolSize 20
PassengerMaxInstancesPerApp 4
PassengerPoolIdleTime 3600
PassengerHighPerformance on
PassengerStatThrottleRate 10
PassengerSpawnMethod smart
RailsAppSpawnerIdleTime 86400
PassengerMaxPreloaderIdleTime 0
DocumentRootの指定先フォルダは後程作成する(そのためまだhttpdは起動しない)。
RailsEnvはdevelopment(開発)、test(試験)、production(本番)を指定できる。Railsの環境は3つを使い分けられるが、さしあたりdevelopmentでいいだろう。
RailsEnv development
ServerName bookapp.example.com
DocumentRoot "/var/www/rails/bookapp/public"
<Directory /var/www/rails/bookapp/public>
AllowOverride all
Options -MultiViews
</Directory>
</VirtualHost>
◆ アプリケーションの作成
書籍を管理するアプリケーションを作成していくとは述べたとおりである。
/var/www/rails/配下に、bookappというアプリケーションを新規に作成する。
mysqldをここで立ち上げておく。
# systemctl restart mysqld.service
# mysqladmin -u root password "***"
DocumentRootで指定したディレクトリを作成する。
# mkdir -p /var/www/rails/
Passengerはroot権限でRailsアプリケーションを動かせない仕様になっているので、オーナーを変更しておく。
# chown -R apache.apache /var/www/rails/
# cd /var/www/rails/
ディフォルトで利用するSQLはsqliteなのだが、今回はmysqlを利用することにしよう。そのため'-d'オプションでmysqlを付与している。
# rails new bookapp -d mysql
# cd bookapp
dbアクセス用のパスワードを記載するぐらいで、ディフォルトで使える。
# vi ./config/database.yml
〜snip〜
username: root
password: ***
〜snip〜
database.ymlファイルに基づいてデータベースを作成する。development、test、production用の3つができるはずである。どのデータベースを使うかは先に書いた通り、passenger.confのRailsEnvで指定する。
# rails db:create
個別に指定もできる。
# rails db:create RAILS_ENV=production
createをdropにするとデータベースを削除できる。
dbをのぞいて見る。
# rails dbconsole
これは下と同じである。
# mysql -u root
> show databases;
+---------------------+
| Database |
+---------------------+
| bookapp_development |
| bookapp_test |
| bookapp_production |+---------------------+
確かにできている。
(補足1)
今回作成するのアプリケーションで必要となるgemは同フォルダのGemfileで定義されている。bundlerと呼ばれるアプリケーションごとのパッケージ管理システムにより、アプリケーションごとにgemを管理できる。
パッケージ管理の一般的な利用例をまず見てみる。
$ vi test.rb
require 'hogepiyo'
$ vi Gemfile
source 'https://rubygems.org'
gem 'hogepiyo'
$ bundle install --path=vendor/bundle
$ ls vendor/bundle/ruby/gems/hogepiyo-x.x.x/
Gemfileを修正した場合は、bundleコマンドで読み直しさせること。
$ bundle update
実行する。
$ bundle exec ruby test.rb
イメージがついただろう。
アプリケーションを実行するrailsのバージョンを指定することもできる。
$ vi Gemfile
gem 'rails', '3,2,13'
◆ 確認
httpdを起動させる。
# systemctl restart httpd.service
ブラウザからアクセスして確認する。
http://x.x.x.x/
DocumentRootで指定した、/var/www/rails/bookapp/public 配下のindex.htmlが読み込まれる。
"Welcome aboard" と出ていれば成功である。"About your application's environment" をクリックしアプリケーション環境に問題ないかも確認しておこう。
ここからコントローラ、ビュー、モデルと作成していくのだが、それはまた次回の
Railsを使ったアプリケーション開発 (その2 基礎編)で。
登録:
投稿 (Atom)