yum からのインストールだと現在、ver 1.8.7 がインストールされる。最新の安定番を付きたい場合、ソースからのみ。
# yum install ruby rubygems
Rubyをインストールするにあたり、JSONに似たYAMLというのを利用するため、libyaml を導入する必要がある。
# wget http://pyyaml.org/download/libyaml/yaml-0.1.6.tar.gz # tar zxvf yaml-0.1.6.tar.gz # cd yaml-0.1.6 # ./configure # make # make install
libyaml は、通常のCentOSなどの通常のディストリビューションの yum には含まれないため、yum のリポジトリに、libyaml を含む リポジトリーを yum に登録する必要がある。その後、libyaml-devel をインストールする。
# rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm # yum install libyaml-devel
※このURLは、このページに含まれている、PackagesのリンクURLを利用する。
Rubyをコンパイルするためのライブラリを一式インストール。
# yum groupinstall "Development Tools" # yum install openssl-devel readline-devel zlib-devel curl-devel # yum install ImageMagick ImageMagick-devel ipa-pgothic-fonts <- option
Rubyの公式サイトはこちら。ここからソースをダウンロードしてコンパイルする。また、Ver1.9 移行は gem の同梱されるようになったので、本体をコンパイル&インストールすると一緒に gem もインストールされる。
# wget http://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.gz # tar zxvf ruby-2.4.1.tar.gz # cd ruby-2.4.1 # ./configure --with-openssl-dir=/usr/local/ssl --enable-shared --disable-install-doc # make # make install
configure オプション | 値 | 概要 |
--with-openssl-dir= | /usr/local/ssl | インストールされている、OpenSSLのフォルダ位置を指定 |
--enable-shared | sharedモードで作成。基本はこのオプションを付けておいたほうが良い | |
--disable-install-capi | C APIのドキュメントをインストールしない。推奨 | |
--disable-install-rdoc | rdoc indexesのドキュメントをインストールしない。推奨 |
出来上がった、 ruby がどのような、configure オプションで作られたかを確認したい場合。
# ruby -r rbconfig -e 'puts RbConfig::CONFIG["configure_args"]'
Ruby on railsとは、rubyを利用したWEB開発フレームワークであり、WEBアプリの開発の効率を高めるものです。
# gem update --system # gem install rails
railsでは、railsのURLに来たものを、config/routes.rb が拾い上げ、仕分けを行いますが、基本は以下の様な仕組みとなっている。詳しくはここ
# vi config/routes.rb get "users/show/:username" => "users#show"
これは、http://host/users/show/xxxx というURLが来たら、username という変数に xxxx を代入して、usersコントローラの showという関数に渡すということです。コントローラ側のプログラムでは、params[:username] という形でこのURLの変数を受け取ることが出来る。
# vi app/controllers/users_controller.rb @user = Hash.new @user[:username] = params[:username]
ここで定義された @user 変数は、app/views/users/show.html.erb の中で利用できるようになるが、@params は変数スコープの関係でコントローラ内でのみしか利用できないため、上記の様に一度、別の変数に設定する必要がある。
app/controllers/users_controller.rb で設定された値は、ビュー画面においてHTMLに置き換えることで画面にその内容を表示する。
# vi app/views/users/show.html.erb <p><%= @user[:username] %></p>
この「<%=」から、「%>」の範囲が、Rubyの変数が参照できる範囲であるという記号であり、最後の拡張子は Embed RuBy の略であり、この拡張子のものは、内部のこの範囲のものをHTMLに動的に展開してからHTMLファイルとして表示する仕組みとなる。
※このerbは、HTMLとしてコメントしてもRuby自体は展開されてしまうため、<%- if false -%> .....コメントしたい行.....<%- end -%> という形で、囲ってしまうのが良い
WEBアプリでは、データの保存には基本データベースを利用する。そのためRailsではデータベースを簡単にアクセスするための仕組みが準備されている。
Railsでは、データベースとの接続には、config/database.yml によって、データベースとの接続方法を定義することで、コントローラ(実際のアプリプログラム)内で簡単にデータベースの操作を行うことができ、データの項目の作成や追加などもデータベースを操作する感覚ではなく、プログラム内のテーブルを操作するような簡単な手続きで記述できる。
# rails g model user name:string username:string address:string
このコマンドは、g = genarate(作成) user = (ユーザーというテーブル) name:string, username:string, address:string (テーブル内の各項目の設定)という意味であり、これによってDBのテーブルを作成する指示を行う。
※コントローラは、users という複数形であったなら、テーブルは1つのデータの単位になるため、テーブル名は user という単数形にすること
また項目を間違えた場合などは、
# rails d model user
という形で、一度 destory して、設定を破棄してから再度 generate すると良い。
上記でデータベースのレイアウトを、db/migrate/20140312110338_create_users.rb のファイル(数字の部分は上記コマンドを実行した日付時間)に、データベースの構造が作成される。その後、この情報を反映させるために、下記のコマンドを実行する。
# rake db:migrate RAILS_ENV=production
ちなみに、このコマンドは何度実行しても問題ない。
作成されたテーブルに初期データを入れる方法は、db/seeds.rb に設定する。
# vi db/seeds.rb @user = User.new @user.name = 'John' @user.username = 'Jonny' @user.address = 'Kanagawa, Japan' @user.save @user = User.new @user.name = 'Micheal' @user.username = 'Mike' @user.address = 'Tokyo, Japan' @user.save
上記のように、1つのレコード毎に作成、設定、保存と行うことでデータベースに初期値を設定できる。
# rake db:seed RAILS_ENV=production
このコマンドが実際の初期値データをデータベースに書き込む実行コマンドとなる。
※実際のデータベース内におけるテーブル名は、複数形になるため上記であれば、users というテーブル名になる。
<検索:文字列>
# vi app/controllers/users_controller.rb @user = User.find_by(:username => 'search_name') <- これはテーブルのusernameという項目で、search_name という名前のレコードを取得する関数。
<検索:ID>
@user = User.find(xxx) <- xxxは数字
※もし検索し0件だった場合には、nil が入るので注意。特に表示上の都合で @user をそのまま利用したい場合には、Hash.new でモデルデータを作り直す必要がある。
# vi app/views/userinfos.html.erb <%= form_for Userinfo.new do |f| %> <%= f.label :title %> <%= f.text_field :title %> <%= f.label :content %> <%= f.text_area :content %> <%= f.submit %> <% end %>
ルーティングファイルに、入力画面のデータをコントローラに渡す旨を記述する。
# vi config/routes.rb post "userinfos" => "userinfos#create"
# rails g controller userinfos index show
これは、users という機能に、index と show 関数を追加する旨を記述している。
<コントローラーで before_filter時に引数を渡す方法。>
before_filter :only => [:edit, :update, :destroy] do |c| c.NewFilterFunction( params[:id] ) end def NewFilterFunction (id) project = Project.find(id) redirect_to signin_path unless project.hidden end
# gem install rails
これだけ。
ちなみに、gem に登録されている機能のリストは、以下のコマンド。
# gem list --remote
インストールの確認をするには、サンプルの作成と表示が手頃である。
# rails new test-rails <- サンプルの作成 # cd test-rails # rails s <- 作成したものを rails の簡易サーバで起動
その後、WEBプラウザーで表示の確認(ポートの3000番を開けておくこと)
http://localhost:3000/
# export RAILS_ENV=production
バージョンの確認
# rails --version
railsのプロジェクトを自身のサーバ機能で起動。(ポートは 3000)
# rails s
WEBサーバーとの連携にはRuby on Railsで構築されたものなど、RubyのウェブアプリケーションのソフトウェアデプロイメントができるWEBサーバーモジュールが必要となる。
Ruby用のwebserver、nginxをプロキシーとしてrailsなどのアプリを利用した場合などに利用する。公式ページはここ。
# vi Gemfile gem 'thin' gem 'execjs' gem 'therubyracer'
# gem install thin
<socketでの接続> nginxの設定ファイルに以下の行を追加。(php-fpmなどと同じ)
server { location /redmine { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; proxy_read_timeout 300; proxy_pass http://redmine; } location ~ .*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO)$ { root /var/www/htdocs/redmine/public; index index.html; expires 30d; break; } } upstream redmine { server unix:/usr/local/nginx/tmp/thin.0.sock; server unix:/usr/local/nginx/tmp/thin.1.sock; server unix:/usr/local/nginx/tmp/thin.2.sock; server unix:/usr/local/nginx/tmp/thin.3.sock; }
※上記の例では、起動するサーバーの数は4つ。
<ポートでの接続>
proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Real-IP $remote_addr; location /remote { proxy_pass http://proxy.mydomain.com:3000; proxy_redirect default; }
※proxy項目は locationの中でも問題ない。
<起動>※なぜかbundle exec を先頭につけないと起動しない。
# bundle exec thin start -e production -s 4 -S /usr/local/enginx/tmp/thin.sock
オプション | 値 | 概要 |
-e | production(初期値=development) | RAILS_ENVの設定を行う |
-s | 4 | 起動するサーバーの数 |
-S | /usr/local/enginx/tmp/thin.sock | ソケット接続する場合のsockファイルの位置 |
-p | 3000 | ポート接続の場合のポート番号 |
-a | (初期値=0.0.0.0) | バインドするIPアドレス |
--ssl | SSL通信を有効化 |
サーバー数を指定した場合、サーバの数に応じてsockファイルが作成されるため、nginx.conf で指定するソケットファイル名に注意が必要。
(例:-s 2 で2つthinサーバを起動した場合、指定した場合ソケット名を「thin.sock」と指定しても、nginxからは、thin.0.sock thin.1.sock などとファイル名の中に、数字が追加されたファイル名になる)
※socketで、Thinを起動した場合は「Thin起動後」webサーバー側も再起動が必要
<停止>
# thin stop -e production -s 4 -S /usr/local/nginx/tmp/thin.sock
※起動時と同じ引数である必要がある。
テストなどでは上記のコマンドラインからの実行でもよいが、サーバーでの正式動作の際には自動的に起動するようにする。
<myapp.ymlの作成>
# cd <railsプロジェクトフォルダ> # thin config -C myapp.yml -e production -s 4 -S /usr/local/nginx/tmp/thin.sock
<myapp.ymlの例>
--- chdir: "/var/www/site/collavier.com/redmine-2.4.3" prefix: /redmine <- http://domain/redmine などサブディレクトリにする場合 environment: production user: redmine timeout: 30 log: log/thin.log pid: tmp/pids/thin.pid max_conns: 1024 max_persistent_conns: 100 require: [] wait: 30 threadpool_size: 20 servers: 4 socket: "/usr/local/nginx/tmp/thin.sock" <- socketの場合、portの場合は port: 3000 などに。 daemonize: true
<テスト動作>
# bundle exec thin start -C myapp.yml
<サービス登録>
thinと較べてデプロイ時間が短くなる。
# gem install unicorn
GemfileにUnicornを利用する旨設定
# vi Gemfile gem 'unicorn'
詳しくはこのページがわかりやすい。
# vi config/unicorn.conf.rb working_directory "/var/www/html/redmine" worker_processes 4 timeout 75 listen 3000, :backlog => 2048 # default 8080 #listen "tmp/run/unicorn.sock", :backlog => 64 pid "tmp/pids/unicorn.pid" stderr_path "log/unicorn_err.log" stdout_path "log/unicorn.log" preload_app true before_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! old_pid = "#{ server.config[:pid] }.oldbin" unless old_pid == server.pid begin Process.kill :QUIT, File.read(old_pid).to_i rescue Errno::ENOENT, Errno::ESRCH end end end after_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end
<サブフォルダで起動する場合、config.ru も修正>
# vi config.ru if ENV['RAILS_RELATIVE_URL_ROOT'] map ENV['RAILS_RELATIVE_URL_ROOT'] do run RedmineApp::Application end else run RedmineApp::Application end
# bundle exec unicorn_rails -c config/unicorn.conf.rb -E production -D --path /redmine
# kill -USR2 (masterのpid)
Passengerは、WEBサーバーのモジュール方式で、提供されるため nginx のように モジュールを別プロセスにして、リクエストのレスポンス遅延を回避するような特徴を持つWEBサーバーの場合、膨大な同時アクセスでトラブルが発生する可能がある。
# gem install passenger
このあと、利用するWEBサーバーに合わせたモジュールをインストールする。
# passenger-install-nginx-module
設定ファイルへの追加
http { passenger_root /usr/local/lib/ruby/gems/2.1.0/gems/passenger-4.0.33; passenger_ruby /usr/local/bin/ruby; passenger_instance_registry_dir /var/tmp/passenger-instreg; } server { passenger_enabled on; passenger_base_uri /mydocs; }
※この部分は上記インストラーがインストール終了時に通知する。
# passenger-install-apache2-module
ステータス
# passenger-status
メモリ利用状況
# passenger-memory-stats
Rubyすべての文法についての説明はRubyのリファレンスページw参照。ここでは特徴的なポイントだけを説明する。
Rubyでは、後置if文という表現がある。
return if flag
これは、
if flag then return end
と機能としては同じ。もしflagがtrueなら、return するという英語の表現のような文法。そのため、C言語でよく使われる else if を使ったifのネスト表現ができない。そのため、Rubyでは、elsif という else if と同じ機能を果たす専用の識別子を準備している。
Rubyにおいて、イテレータは他の言語の様に特別に準備された構文ではなく、Rubyの言語体系にスムーズに組み込まれている。Javaなどの他の言語ではイテレータは特別なオブジェクトの型になっており、その抽象化されたオブジェクト変数を基本に構文が考えられているが(foreachなどは典型例)、Rubyではオブジェクト自体が繰り返しを意味するメソッドを準備し、それをブロック文(クロージャーと言う言語もある)へ渡すという仕組みとなっている。
3.times {|c| print "res=" + c.to_s + "\n" }
これは3回、大括弧のブロック文を実行する。その際に繰り返しの数字を、| で囲っているcに代入して繰り返す。という内容になる。これは
name = [ "aaa", "bbb", "ccc" ] name.each {|c| print "res=" + c.to_s + "\n" }
このように、文字列の配列を繰り返す事も可能となる。実際1行に書くと分かりづらいが下記のように改行し説明すると理解し易い。
name.each{ |引数| print "res=" + 引数.to_s + "\n" }
ちなみに、同様の事を do ~ end で記述すると。
name.each do |c| print "res=" + c.to_s + "\n" end
ようするに、多くのブロック文やクロージャーに触れて出てくるように、ブロック文は無名関数として定義され、その引数にオブジェクト自体が繰り返しメソッド(timesやeachなど)にしたがって、複数回呼び出しを行っているという仕組みになる。また単純配列だけでなく
def name yield 10,100 yield "look" end name { |c| print "res=" + c.to_s + "\n" }
結果
res=10 res=look
と表現することもできる。ここでわかることは、yield 句を持つオブジェクトは、each や times などの繰り返しメソッドを必要とせず、そのままブロックに渡すことで、yield句のすべての値が終わるまで繰り返しブロック文が呼び出される。またyield句の1行目のように、2つの引数を渡すようになっていても、実行時にエラーはでない。また、
name { |c, d| print "res=" + c.to_s + ":" + d.to_s + "\n" }
結果
res=10:100 res=look
このように、第2引数を取得するようにすると、2つ目の値(ここでは yield 10,100 なので 100 の値)が取得され、存在しない yield 句のデータでは、nil が返される。
{ ... } の方が do ... end ブロックよりも強く前に結合するため、do を使うとブロックが切り離される。
foobar a, b do .. end | foobarの引数はa, bの値とブロック |
foobar a, b { .. } | ブロックはメソッドbの引数、aの値とbの返り値とがfoobarの引数 |
str.each_byte | 文字列の一文字ずつ順に渡す |
str.each_line | 文字列の一行ずつ順に渡す |
1.upto(5) | 1, 2, 3, 4, 5 を順に渡す |
5.downto(1) | 5, 4, 3, 2, 1 を順に渡す |
1.step(10, 2) | 1, 3, 5, 7, 9 を順に渡す |
基本はJavaScript等と同じだが、記述によって速度が違う。ここ また、JavaScript等と違い数字を自動的に文字に変換してくれないため、
a = "text" + 3
はエラーになる。よって明示的に
a = "text" + 3.to_s
という形で、数字を文字に変換する to_s メソッドを利用する。逆の場合は
a = "1000".to_i
となる。
ruby 1.9 移行、他の linux コマンドのように、require './readfile.rb' のように、「./」をつける必要がある。
下記のようなページが表示され、railsの画面がでない場合。
Page not found The page you were trying to access doesn't exist or has been removed. Back
主な理由
とりあえずデータベースを削除する。
# sqlite3 db/development.sqlite3 sqlite> .tables <- テーブル一覧の表示 sqlite> drop table Table_Name; <- Table_Name テーブルの削除 sqlite> .exit # rails d model Table_Name
このあと、再度、generate する。
config/database.yml や、configuration.yml に TAB がある。
certificate verify failed (https://api.rubygems.org/specs.4.8.gz)
gemが参照している証明書が古いために発生する。基本的に OpenSSL と、Ruby を最新版に更新することで、解消する。確認には下記 system update を行ってみると良い。
# gem update --system
またアップデート後に bundler の再インストールも忘れないこと
# gem install bundler
参考:rubygem.orgのSSL証明書の内容を確認する。
# openssl s_client -connect rubygems.org:443 -showcerts -status < /dev/null