ラベル ruby の投稿を表示しています。 すべての投稿を表示
ラベル ruby の投稿を表示しています。 すべての投稿を表示

2011年6月8日水曜日

ubuntu 10.04 で Ruby(環境構築編) その2

だいぶ前に ここで RVM の設定方法を書き込んだが、今ではだいぶ楽になっていた。
ビックリしたのでメモ。

1.事前準備

rvm を動作させるのに必要なものを一式インストールする。
sudo aptitude install git-core curl zlib1g-dev

rvm をセットアップする場所を作成して、移動する。
mkdir ~/.rvm
cd ~/.rvm

2.インストール

以下のコマンドを実行する。
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
すると、カレントディレクトリに rvm 絡みが一式できてる。(ここでは ~/.rvm 配下)

後は、コンソールに表示されている内容の修正を .bashrc or .bash_histry に加える。
具体的には、
#.bashrc
[ -z "$PS1" ] && return
の欄を
#.bashrc
if [[ -n "$PS1" ]] ; then

  # ... original content that was below the '&& return' line ...
  [ -z "$PS1" ] && return

fi # <= be sure to close the if at the end of the .bashrc.

# This is a good place to source rvm v v v
[[ -s "/home/matsumoto/.rvm/scripts/rvm" ]] && source "/home/matsumoto/.rvm/scripts/rvm"  # This loads RVM into a shell session.
に書き換えるだけ。

書き換え後は、
source .bashrc
で変更を反映させる。



■おまけ

RVM のコマンドリスト(少しだけ)
rvm list インストールされている Ruby を一覧表示
rvm list known rvm でインストール可能なすべてのバージョンを表示
rvm install version 指定されたバージョンの Ruby をインストール
rvm [use] version [--default] 使用する Ruby を選択する。
--defaultを指定すれば、それが常に利用される。
rvm uninstall version 指定したバージョンの Ruby を削除する。
rvm --help 困ったときはヘルプを見るべし!


■最後に

RVM 自体のアンインストール
rvm implode

した後に、RVM_HOME のソース類をゴソッと削除して、.bashrc or .bash_histry を修正する。

かなぁ。

2011年4月8日金曜日

Rails3 routes

やはり触れることになってしまった routes.rb。これを期に意味不明な部分を理解しよう。
勉強して得られた情報をメモ。

routes.rb にて生成される URL については rake routes コマンドにて確認できる。
記載する出力結果はすべて rake routes にて出力された結果です。


match(path, options={})


route 師弟の基本。アクセス可能な path を指定してやることで、HTTP リクエストを処理できるようになる。
match "foo/bar"
# foo_bar  /foo/bar(.:format) {:controller=>"foo", :action=>"bar"}
path は必ず一つ以上 "/" を入れてやる必要がある。
  • match "foo" => NG
  • match "foo/bar" => :controller=>"foo", :action=>"bar"
  • match "foo/bar/buz" => :controller=>"foo/bar", :action=>"buz"
"/" を複数指定した場合、controller の namespace を表すように解釈される。

以下指定可能オプション。(全部じゃないかも)

:controller
:action
動作させるコントローラとアクションを指定する。
必ずセットで指定する。
path に "/" を入れなくてもこのオプションを指定してやれば解釈されるようになる。
match "foo", :controller=>"foo", :action=>"bar"
# foo  /foo(.:format)  {:controller=>"foo", :action=>"bar"}
:to :controller, :action の短縮形。"#" でコントローラとアクションを区切って記述する。
match "foo", :to=>"foo#bar"
:to の記述自体を短縮する方法もある。
match "foo"=>"foo#bar"
:via HTTP メソッドを付加する。
match "foo/bar", :via=>:get
# foo_bar GET /foo/bar(.:format) {:controller=>"foo", :action=>"bar"}
:as ルート名を指定する。ルート名は form_tag や link_to などで指定できる名前で、その名前に該当する path を生成して form を作成してくれる。
match "foo/bar", :as=>"bar"
# bar GET /foo/bar(.:format) {:controller=>"foo", :action=>"bar"}


get

post

put

delete


match の :via オプションの HTTPHelper メソッド。
指定可能なパラメータは match と同様。なので
get "foo/bar", :via=>:delete
なんていうふざけた記述もちゃんと解釈してくれる。(HTTP メソッドは GET になります)


resource

resources


Rails のルールに従って RESTful 的な URL を自動で生成してくれる有名なメソッド。
単数形の場合は resource を、複数形の場合は resources を利用する。*指定する名前も単数形、複数形を意識して指定してやる。(resource :foo, resources :foos)
二つの違いは一覧出力 URL (scaffold 生成時の index アクション) の有無の違い。

以下指定可能オプション。(全部じゃないかも)
:as ルート名に利用する別名。
resource "foo", :as=>"bar"
#   bar POST   /foo(.:format)      {:action=>"create", :controller=>"foos"}
# new_bar GET    /foo/new(.:format)  {:action=>"new", :controller=>"foos"}
#edit_bar GET    /foo/edit(.:format) {:action=>"edit", :controller=>"foos"}
#       GET    /foo(.:format)      {:action=>"show", :controller=>"foos"}
#       PUT    /foo(.:format)      {:action=>"update", :controller=>"foos"}
#       DELETE /foo(.:format)      {:action=>"destroy", :controller=>"foos"}
:controller 処理するコントローラを指定する。
アクション名は Rails ルールに従う必要がある。
resource "foo", :controller=>"bar"
#   foo POST   /foo(.:format)      {:action=>"create", :controller=>"bar"}
# new_foo GET    /foo/new(.:format)  {:action=>"new", :controller=>"bar"}
#edit_foo GET    /foo/edit(.:format) {:action=>"edit", :controller=>"bar"}
#        GET    /foo(.:format)      {:action=>"show", :controller=>"bar"}
#        PUT    /foo(.:format)      {:action=>"update", :controller=>"bar"}
#        DELETE /foo(.:format)      {:action=>"destroy", :controller=>"bar"}
:path URL を置き換える。
resource "foo", :path=>"b/a"
#   foo POST   /b/a(.:format)  {:action=>"create",:controller=>"foos"}
# new_foo GET    /b/a/new(.:format) {:action=>"new",:controller=>"foos"}
#edit_foo GET    /b/a(.:format)     {:action=>"edit",:controller=>"foos"}
#         GET    /b/a(.:format)     {:action=>"show",:controller=>"foos"}
#         PUT    /b/a(.:format)     {:action=>"update",:controller=>"foos"}
#         DELETE /b/a(.:format)     {:action=>"destroy",:controller=>"foos"}
:only 作成される URL を絞り込む。指定されたアクションのみ URL が生成される。
resources "foo", :only=>["index"]
# foo_index GET /foo(.:format) {:action=>"index", :controller=>"foo"}
:except 作成する URL を削除する。指定されたアクションは URL が生成されない。
こう書けば、:only と同じ結果になる。
resources "foo", :except=>["create","edit","new","show","update","destroy"]
# foo_index GET /foo(.:format) {:action=>"index", :controller=>"foo"}
:module controller に namespace を付加する。
resources "foo", :only=>["index"], :module=>"module"
# foo_index GET /foo(.:format) {:action=>"index", :controller=>"module/foo"}

has_many の関係を定義する場合、block を渡して resources を定義する。

resources "foo" do
  resources "bar"
end


scope


URL に namespace を付けるイメージ。controller には付かない所がポイント。
scope "scope" do
  resources "foo", :only=>["index"]
end
# foo_index GET /scope/foo(.:format) {:action=>"index", :controller=>"foo"}

block 内に match(path) を指定した場合、namespace として扱われる。(controller にも scope が付加される)
scope "scope" do
  match "foo/bar"
end
# foo_bar  /scope/foo/bar(.:format) {:controller=>"scope/foo", :action=>"bar"}
:to オプションを付けて controller と action を宣言してやれば、URL のみ対象となる。

以下指定可能オプション。(全部じゃないかも)
:module controller の namespace を指定する。
scope "sco", :module=>"mod" do
  resources "foo", :only=>["index"]
end
# foo_index GET /sco/foo(.:format) {:action=>"index", :controller=>"mod/foo"}
:as ルート名に prefix を付加する。resources は別名に置き換えるがこっちは付加する。
scope "sco", :as=>"as" do
  resources "foo", :only=>["index"]
end
# as_foo_index GET /sco/foo(.:format) {:action=>"index", :controller=>"foo"}

controller のみに namespace を付加したい場合、
scope :module=>"module" do
  resources "foo", :only=>["index"]
end
としてやればよい。


namespace


URL 名, URL と controller に(要は全てに) namespace を付加する。
namespace "nspe" do
  resources "foo", :only=>["index"]
end
# nspe_foo_index GET /nspe/foo(.:format) {:action=>"index", :controller=>"nspe/foo"}

以下指定可能オプション。(全部じゃないかも)
:as ルート名に prefix を付加する。動きは scope と同じ。


controller


controller を一括で指定できる。
controller "foo" do
  get "search"
end
# search GET /search(.:format) {:action=>"search", :controller=>"foo"}
match でエラーになるパターン ("/" なし) も controller を付加してくれてちゃんと動く。
優先度は block 内のメソッドの方が高く、resources "bar" や match "bar/buz" など指定しても適用されない。(:controller=>"bar"になる)

以下指定可能オプション。(全部じゃないかも)
:path URL に prefix を付加する。デフォルトでは controller 名は URL に付加されないので、必要な場合は指定する。
controller "foo", :path=>"foo" do
  get "index"
end
# index GET /foo/index(.:format) {:action=>"index", :controller=>"foo"}
:as ルート名に prefix を付加する。動きは scope と同じ。


root


root ("/") にアクセスされた際の routes を指定する。
root :to=>"foo#bar"
# root  /(.:format) {:controller=>"foo", :action=>"bar"}



長文でダラダラとまとめたが、まだまだ全部でない感じがする。(ソース見た感じ)
けど、これで routes への恐怖心が若干薄まった感がある。

2011年3月30日水曜日

Rails3 :method => :delete が動かない件

環境
  • Windows XP SP2
  • Internet Explorer 6
  • ruby 1.9.2p136 (2010-12-25) [i386-mingw32]
  • Rails 3.0.3

上記環境にて、link_to :method => :delete が正しく動作しない。
scaffold で生成したコンテンツでもダメだった。
原因を調査してみたら、rails.js 内の以下の箇所で TypeError が発生していた。
function handleMethod(element) {
  var method = element.readAttribute('data-method'),
      url = element.readAttribute('href'),
      csrf_param = $$('meta[name=csrf-param]')[0],
      csrf_token = $$('meta[name=csrf-token]')[0];

  var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
  element.parentNode.insert(form); // ←←←この箇所

  if (method !== 'post') {
    var field = new Element('input', { type: 'hidden', name: '_method', value: method });
    form.insert(field);
  }

  if (csrf_param) {
    var param = csrf_param.readAttribute('content'),
        token = csrf_token.readAttribute('content'),
        field = new Element('input', { type: 'hidden', name: param, value: token });
    form.insert(field);
  }

  form.submit();
}

debug してみると、たしかに element.parentNode に insert という function は存在していなかった。
とりあえず、以下のように修正することで回避可能。
//  element.parentNode.insert(form);
  element.insert(form);

以下の環境だと、上記修正を行わなくてもちゃんと動いた。
  • Ubuntu 10.04
  • Google Chrome 10, Firefox 4.0
  • ruby 1.9.2p136 (2010-12-25 revision 30365) [i686-linux]
  • Rails 3.0.4

怪しいのは IE6。別バージョンで試すことができない環境なのでどうしようもない。
んー、おかしい。

2011年3月26日土曜日

Rails3 selectbox を動的に変更する。

Rails3 で selectbox (combobox) の中身を動的に入れ替える処理が必要になった。
ググってみると大概 observe_field を利用した Ajax.update を行うものだったが、Rails3 には
observe_field が削除されている。(正確には Rails2.3.9 で削除されたっぽい)
なので無い脳ミソをフル稼働させて考えてみた結果をメモ。


■仕様(やりたい事・目指した事)

  • selectboxA を変更したら、その内容で selectboxB の内容が置き換わる。
  • n段に対応。(selectboxA → selectboxB → selectboxC → ... → selectbox(N))
    今回は大分類・中分類・小分類の 3 段で考える。
  • 全ての selectbox の先頭に :inclide_blank => true を入れる。
  • DRY を徹底する。(同じコードはなるべく書かない)

調べてみるとやり方はかなり豊富。仕様と照らし合わせてどのやり方をチョイスするか選んだ方がよさそう。
今回の仕様から、RJS つかって動的にコンテンツを更新する方法にした。


■考え方

まず selectbox のデータを格納する model を考える。今回は kind(分類) という model を作成する。
kind
PKid : integer
 name : string
FKkind_id : integer
kind_id が外部キーとなっており、自分の親のキーを保持する。
(中分類のデータなら所属する大分類のIDを保持する)

次に html タグの動的入れ替えだが、以下の範囲を入れ替えるように考えた。
<p id="middle_select">
<select id="kind_id_middle"> <option></option> *黄色の部分を Ajax で入れ替える </select>
</p>
理由は、selectbox の先頭に blank option をつけたかったから。直に <option value=""></option>
タグを書けば option 範囲の入れ替えでもいけるのだが、それはあまりやりたくなかった。(要こだわり)


■実装

model は作ってあり、データも適当にいれているものとする。
大分類の kind_id は 0 を指定しておく。(TOP レベルで親はいませんという意味で)
必要な routes.rb は記述してあるものとする。
参考データ
idnamekind_id
1大分類10
8中分類11
22中分類21
43小分類18
44小分類28
65小分類322

初期表示時の view。
# select.html.erb

<%= label "kind_id", "large", "大分類:" %> <%= select "kind_id", "large", Kind.where("kind_id = 0").map{|p| [p.name, p.id]}, {:include_blank => true}, {:onchange => remote_function(:url => {:action => "change_select"}, :with => "'kind_id[large]=' + escape(this.value)")} %>

<%= render :partial => "middle_select", :locals => {:middle_kinds => @middle_kinds} %>

<%= render :partial => "small_select", :locals => {:small_kinds => @small_kinds} %>

ポイントは
  • render 使って動的入れ替えする部分を外だしにする。(RJS でも render すれば DRY になる)
  • observe_field がないので、onchange イベントに remote_function ひっつける。
  • remote_function :with で大分類の値を POST する。
  • 複数のコンテンツをいっぺんに変えるため (大分類 → [中分類, 小分類]) remote_function :update は未指定。

中分類の view。select.html.erb と同じ階層に作成する。
# _middle_select.html.erb
<%= label "kind_id", "middle", "中分類:" %>
<%= select "kind_id", "middle",
      middle_kinds.map{|p| [p.name, p.id]},
      {:include_blank => true},
      {:onchange => remote_function(:url => {:action => "change_select"},
                                    :with => "'kind_id[middle]=' + escape(this.value)")} %>

小分類の view。select.html.erb と同じ階層に作成する。
# _small_select.html.erb
<%= label "kind_id", "small", "小分類:" %>
<%= select "kind_id", "small",
          small_kinds.map{|p| [p.name, p.id]},
          {:include_blank => true} %>
中分類には選択したら小分類を入れ替える必要があるので onchange イベントを追加するが、小分類は入れ替え処理が不要なので、onchange は省略する。

次は controller。
# controller.rb
# 初回表示時 action
def select
  @middle_kinds = []
  @small_kinds = []
end

# onchange 時のイベント
def change_select
  if params[:kind_id][:large]
    @middle_kinds = params[:kind_id][:large] != "" ?
        Kind.where("kind_id = #{params[:kind_id][:large]}") :
        []
    @small_kinds = []
  else
    @middle_kinds = nil
    @small_kinds = params[:kind_id][:middle] != "" ?
        Kind.where("kind_id = #{params[:kind_id][:middle]}") :
        []
  end
end
初回表示時は大分類だけに値が設定されているシチュエーションなので、中分類、小分類は空にしておく。
change_select イベントは大分類、中分類で共同で利用するイベント。params[:kind_id][:large]が存在すれば(nil でなければ)大分類の change イベントと判別できるので、大分類変更時は、中分類を読み込んで小分類をリセットする。
中分類変更時は (params[:kind_id][:middle] != nil) 小分類のみ書き換えするため、あえて @middle_kinds に nil を設定して書き込み対象外の判別が行えるようにした。(後述 RJS 参照)

最後に RJS。select.html.erb と同じ階層に作成。
# change_select.js.rjs
if @middle_kinds
  page.replace_html "middle_select", :partial => "middle_select", :locals => {:middle_kinds => @middle_kinds}
  page.visual_effect :highlight, "middle_select"
end
page.replace_html "small_select", :partial => "small_select", :locals => {:small_kinds => @small_kinds}
page.visual_effect :highlight, "small_select"
@middle_kinds == nil 時は更新不要なので、更新するかしないかを最初に判定している。
一応、視覚的効果があるほうがインターフェース的に親切らしいので、動的入れ替え後は effect した。


■最後に

今回は複数更新することを念頭に入れていたため RJS を利用したが、1個のみの更新 (大分類 → 中分類) だけだったら、remote_finction :update => "middle_select" を指定して、controller で render :partial => "middle_select" ってする方が簡単。けど、こっちの方が応用 & 拡張性に優れている気がするので、RJS 積極的に使っていこうかな。

以上。長文でわかりづらく、失礼しました。

2011年3月25日金曜日

Rails3 text_field と text_field_tag の違い

なんか、今更だけどやっと違いが分かったのでメモ。

text_field_tag

<%= text_field_tag 'user_id' %>
<input id="user_id" name="user_id" type="text" />

text_field

<%= text_field 'person', 'user_id' %>
<input id="person_user_id" name="person[user_id]" size="30" type="text" />

違いは
  • size 属性が自動でつく。
  • POST パラメータがハッシュ形式になる。params[:user_id] と params[:pserson][:user_id] の違い

一番大きいのは、パラメータ値がハッシュ形式で取得できるかどうかの部分。

他の ヘルパメソッドもすべて同じ。(password_field や check_box など)

Rails 1.x から時間の合間見て触ってきて、やっと理解できた俺っていったい。。。(by キートン山田)

Rails3 fields_for

使い道は思いつかないが、便利そうなのでメモ。
form_for は <form></form> を生成するが、fields_for は <form> を生成しない。
で、form_for と同じ POST 時のパラメータ値を Hash 形式にできる。

■form_for

<%= form_for :person do |f| %>
  ID: <%= f.text_field :user_id %>
  Name: <%= f.text_field :name %>
<% end %>
<form accept-charset="UTF-8" action="/form/input" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="Rtch9vUwmDWmniDy/IsMetQhhfnbzp9lHXV6YAe2PwA=" /></div>
  <input id="person_user_id" name="person[user_id]" size="30" type="text" />
  <input id="person_name" name="person[name]" size="30" type="text" />
</form>

■fields_for

<%= fields_for :person do |f| %>
  ID: <%= f.text_field :user_id %>
Name: <%= f.text_field :name %>
<% end %>
ID: <input id="person_user_id" name="person[user_id]" size="30" type="text"/><br/>
Name: <input id="person_name" name="person[name]" size="30" type="text"/>

以前書いた check_box の配列化なんかのコードが
<%= fields_for :dinner do |field| %>
  <%= field.check_box "zensai" %>前菜
  <%= field.check_box "supe" %>スープ
  <%= field.check_box "main" %>メインディッシュ
  <%= field.check_box "dezart" %>デザート
  <%= field.check_box "drink" %>ドリンク
<% end %>
と、なんかスッキリと書ける。

Rails3 HTML5 タグの出力

Rails3 で HTML5 サイト作成のため、イロイロ調査した結果をメモ。

HTML5 タグを吐き出す基本的なやり方は、
<%= text_field_tag 'find', nil :type=>'search' %>
<input id="find" name="find" type="search"/>
と、text_field_tag の html_options で type 属性を指定する。
Rails ではちゃんと上記コードを簡略化するためのヘルパメソッドが用意されている。


HTML TagFormHelper Method
<input type="search"/>search_field
<input type="tel"/>telephone_field(phone_field)
<input type="url"/>url_field
<input type="email"/>email_field
<input type="number"/>number_field
<input type="range"/>range_field

日付系 (date, datetime 等) や color といったものは見当たらなかった。
なので、ヘルパメソッドが存在しないタグは text_field を直接利用するしかない(?)

2011年3月22日火曜日

Rails チェックボックスの配列化(修正)

昔、こんな記事を書いたが、
こんな配列化は意味がないことに気づいたので加筆。

check_box_tag

以下のように記述すると、
<%= check_box_tag "print" %>印刷する
生成される HTML は
<input id="print" name="print" type="checkbox" value="1" />印刷する
となる。
submit した際の parameter 値は
選択時 => "print"=>"1"
非選択時 => "print"=>nil
となる。
ruby では false と nil は false 扱いとなるため、単純に if で params[:print] と判定すれば
ON, OFF の判定ができるため、簡単に記述できる。

check_box

以下のように記述すると、
<%= check_box "print", "enabled" %>印刷する
生成される HTML は
<input name="print[enabled]" type="hidden" value="0" /><input id="print_enabled" name="print[enabled]" type="checkbox" value="1" />印刷する
となる。
submit した際の parameter 値は
選択時 => "print"=>{"enabled"=>"0"}
非選択時 => "print"=>{"enabled"=>"1"}
となる。
要は、check_box タグを利用すると、checkbox を Hash でパラメータ渡しできるようになる。
なので、配列化したい場合は、それぞれの項目に名前をつけてやって Hash の key として扱ってやればよい。

例) ディナーのコースを選択する。必要なコースがあればチェックをつける
<%= check_box "dinner", "zensai" %>前菜
<%= check_box "dinner", "supe" %>スープ
<%= check_box "dinner", "main" %>メインディッシュ
<%= check_box "dinner", "dezart" %>デザート
<%= check_box "dinner", "drink" %>ドリンク
これで、ディナーパラメータ値にハッシュとして配列化されてコントローラに渡ってくる。

無理に配列化するメリットは何もない。意味不明な index で値を取得する必要も
ないし、未選択時に飛んでこないなんてこともない。

2011年3月3日木曜日

Ruby: 指定された日が何月の何周目かを求める

タイトルのようなものが必要になった。
考えるのが面倒くさかったため、ネットで答えを探したが
うまく見つけることができなかったため、固い頭を使って
考えてみた。
その結果を晒します。

■仕様
  • 月曜日基点で考える。
  • 月曜日が所属する月にその週は属する。
例でいうと以下のとおり。(2011-03-03の場合)
2011年
2月-3週 21 22 23 24 25 26 27
2月-4週 28 1 2 3 4 5 6
3月-1週 7 8 9 10 11 12 13

実際のコードは以下。
def mweek(date)
  day = date - (date.cwday - 1)
  base_month = day.month

  week = 0
  (1..5).each do |index|
    day -= 7
    if base_month != day.month
      week = index
      break
    end
  end

  { :month => base_month, :week => week}
end

解説:
cwday で週を数字化して月曜日が 基点になるように補正。日付を移動させる。
あとは基点月が所属する月から何周目かをカウントするだけ。
復帰値は月と何周目かの Hash 値。複数の復帰値が返せる curl や scala が便利と感じる。
*よくテストしていないので、BUGがあるかもしれません。

2011年2月6日日曜日

Rails3 Bundler

Rails アプリ毎に Gemfile の依存関係を管理するための仕組み。

$RAILS_APP 直下にある Gemfile を編集する。

# Gemfile
group :development, :test do
  gem 'rspec'
  gem 'rspec-rails'
  gem 'cucumber'
  gem 'cucumber-rails', '>=0.4.0.beta.1'
end

Gemfile のインストール
bundle install vendor/bundle

インストール先の推奨は vendor/bundle らしい。
未指定の場合、ruby/gems 配下にインストールされ、全環境に影響を与えるようになる。

Gemfile の確認
bundle list

削除方法は不明。
とりあえず vendor/bundle 配下をすべて削除して clean インストールする。

2010年5月12日水曜日

ubuntu 10.04 で Ruby on Rails(環境構築編)2

$ rails example
$ cd example
$ rails g scaffold test code:string name:string
$ rake db:migrate

を実行後、config/application.rb をつついて
$ rails s

を実行し、http://localhost:3000/tests にアクセスすると
なにやら怪しげなエラーが発生した。

google先生に質問したところ、英語で
「1.9.1 は非サポートなんで、1.9.2 を使ってね」
と、いうありがたい回答をいただいた。

なのでまた環境構築しないと。。。

□ruby1.9.2のインストール準備
$ sudo apt-get install subversion
$ sudo apt-get install autoconf

□ruby1.9.2のインストール
$ rvm install ruby-head

ruby1.9.2はheadからインストールしないと、rails3は動かない。
preview1では実際 scaffold できなかった。(ruby BUG)

以上。

2010年5月10日月曜日

ubuntu 10.04 で Ruby on Rails(環境構築編)

rvm で ruby をインストールするとすさまじく楽勝。
ただし、事前セットアップがかなり必要なため、そこをメモしておく。

* よく分からないがおそらく ruby インストール前にインストールしておく必要アリ。

□事前セットアップ
$ sudo apt-get install gcc
$ sudo apt-get install build-essential
$ sudo apt-get install bison byacc gperf
$ sudo apt-get install zlib1g-dev
$ sudo apt-get install libreadline5 libreadline5-dev
$ sudo apt-get install libncurses5 libncurses5-dev
$ sudo apt-get install libssl-dev
$ sudo apt-get install sqlite3 libsqlite3-dev
$ sudo apt-get install curl
$ sudo apt-get install git-core


最新が入っていますといわれるものは無視する。
上記パッケージをすべてインストールした状態で
$ rvm install 1.9.1
とかする。

□rails(3 beta3) インストール
$ gem install rails --pre
$ gem install sqlite3-ruby


これで rails3 beta3 が完動する。(rails cも含めて)
もちろん rails g scaffold も動く。
rvm さまさまである。
自力でインストールした際は GEM_PATH の設定や、bindle のエラーなどではまりまくったがすんなり動くところまでたどり着いた。

明日から rails3 使ってみよう!

以上。

ubuntu 10.04 で Ruby(環境構築編)

複数バージョンの Ruby が簡単に切り替えられる rvm を使う。
□必要なもののインストール
1.git
$ sudo apt-get install git-core

2.curl
$ sudo apt-get install curl

3.zlib(開発環境)
$ sudo apt-get install zlib1g-dev

□rvm のインストール
1.github からソースのダウンロード
$ mkdir -s .rvm/src
$ cd .rvm/src
$ git clone git://github.com/wayneeseguin/rvm.git
$ cd rvm
$ ./install


□インストール後に表示されるメッセージに従い、.bashrc を変更
$ vi ~/.bashrc

先頭行に追加
if [[ -s /home/◯◯/.rvm/scripts/rvm ]] ; then source /home/◯◯/.rvm/scripts/rvm ; fi

□1.9.1インストール
$ rvm install 1.9.1

□1.8.7インストール
$ rvm install 1.8.7

各バージョンを利用する場合は
$ rvm 1.9.1

すばらしいな、これ。

2009年1月11日日曜日

irbカスタマイズ

Ruby 技術者認定試験を取得するべく日々Rubyを勉強しています。
そんなとき、やっぱり役にたつのがirb。
手早くロジックが組めて、簡単な動作確認がささっとできる。
そんなirbを使いやすくカスタマイズする方法と
私の環境の公開です。(たいしたことはしてないですが)

irbはHOMEディレクトリ直下に.irbrcファイルを準備
してやることで、irbにmethodが追加できます。
んで、私が追加したのは

@default_file = "~/.edit.rb"

def new (file = @default_file)
system "rm #{file}"
system "vi #{file}"
end

def edit(file = @default_file)
system "vi #{file}"
end

def emacs(file = @default_file)
system "emacs #{file}"
end

def run(file = @default_file)
system "ruby #{file}"
end

def clear
system "clear"
end

です。
irbで作業する際の一番の致命的な箇所は
編集できない点です。
そのため、ファイルに編集するmethodを追加し
ファイルを実行するmethodを追加しています。
デフォルトはHOMEディレクトリに.edit.rbという
ファイルを作成します。引数でファイル名を渡して
やることも可能です。

あとは refe が使えれば完璧なんですがね。

Ruby 1.9.1rc1

去年までは一日1書き込みと決めていたが
時間的余裕があまりとれないため、書き込みができる
&ネタがあればガシガシ書きこむことにした。

私は根っからの Windows ユーザー。
そのため Ruby 1.9.1 rc1 が公開された際
コンパイルできるか不安だった。
その不安は的中した。VC2005 でコンパイルして
みたが意味不明なエラー。ネットで調べても
原因不明。
そのため、ちょっと距離を置いていたところ、
artonさんのMswin32インストール
パッケージのアナウンスを目にした。
やったーと思い、早速インストールしてみたが
irb, gem が動かない!?!?!
またまた挫折した。

そして最終的にとった方法。
VMware 上の Fedora 8 上でコンパイルして
利用しています。
Linux だと一発だった。Windows やめようかな。。。(会社的に無理だけど)

んで、動作確認。シャドーウィングを実験してみることに。

#!/usr/bin/ruby -Ku
# -*- coding: utf-8 -*-
["foo"].each do |s|
["bar"].each do |s|
puts s
end
puts s
end

$ ruby .edit.rb
bar
foo

完璧。

2008年12月17日水曜日

RSpec+autotest+Snarl その2

せっかく作った環境を壊してしまった。(ボーっとして全削除した^^;)
よって再度作り直したところ、autotestが反応しなくなった。
んで、調査した結果、
どうも最新のrspec-railsではTest::UnitとRSpecのautotestを
任意に使い分けができる模様。

Test::Unit

普通に autotest で実行

RSpec

script/autospec で実行


これがわからなかった。
autotestで動かしてたから、いくらspecテスト書いても動かないわけだ。

2008年12月16日火曜日

RSpec+autotest+Snarl その1

今話題の rails テスト環境。
Growl for Windows で本当はやりたかったけど、WebKit 系ポップアップが正しく表示されない(エラーが出る)ので、snarl に変更した際の備忘録。
参考) gan2 の Ruby 勉強日記

  • snarl

  • rspec

  • rspec-rails

  • autotest

  • win32console

  • ZenTest

  • diff-lcs

  • ruby-snarl

  • redgreen


は事前にインストールしておくこと。snarl以外はすべて gems でインストール可能。
.autotestのコードを以下のように。※ ファイルの作成方法は参考サイトを見てね。

# ruby -w
require 'rubygems'
require 'autotest/redgreen'
require 'autotest/snarl'
require 'win32/console/ansi'

Autotest::HOOKS.delete(:interrupt)
module Autotest::Snarl
def self.icon
{
:green => 'rails_ok.png',
:red => 'rails_fail.png',
:pending => 'rails_pending.png'
}
end

def self.snarl title, msg, img=nil
Snarl.show_message(title, msg, icon[img])
end

Autotest.add_hook :ran_command do |at|
results = [at.results].flatten.join("\n")
output = results.slice(/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+pending)?/)
if output =~ /[1-9]\sfailures?/
snarl "FAIL:", "#{output}", :red
elsif output =~ /[1-9]\spending?/
snarl "PENDING:", "#{output}", :pending
else
snarl "PASS:", "#{output}", :green
end
end
end

class Autotest
def self.clear_hook
HOOKS[:red].clear
HOOKS[:green].clear
HOOKS[:pending].clear
HOOKS[:all_good].clear
end
end
#Autotest.clear_hook

参考サイトと違う点(と、いうか色んなサイトを合わせた)を列挙すると、

require 'rubygems'
require 'win32/console/ansi'
Autotest::HOOKS.delete(:interrupt)
snarl "PENDING:", "#{output}", :pending
#Autotest.clear_hook

1.rubygemsでインストールしたので、gems宣言を追加。
2.win32consoleを追加しないと、Snarlに通知されなかった。
3.autotestがCTRL+C*2で停止しないため追加
4.pendingも表示(まだ試してないけど。。。)したかったので追加
5.CTRL+C*2で停止しないためコメント化

で、コマンドプロンプトで autotest を実行すれば
Snarl に通知が無事いきました。

後は、

  • rspec-rails と rspec プラグインの違い

  • ZenTest の設定


が分かり次第、エントリ登録しようと思う。

2008年12月9日火曜日

Ruby でハマッタこと

プライベートでイロイロあって投稿がご無沙汰してきた。
今日、Rubyやっててハマッタことを記録。

irb -Ks にて、

a=%w(1 2 3 4 5)
a.sort {|a, b| b<=>a }
puts a

実行すると、なんと
=>[5, 4, 3, 2, 1]
a=>1

a=1?
配列なのに、なぜ?
a.classするとFixnumになってるし。。。

答えは単純。
配列名とブロック引数名が重複しているためでした。
変数名を変えてやれば正しく動きました。
マイッタ。

2008年11月13日木曜日

10の練習問題 その02

新しくプログラミング言語を覚えたいときに行うべき10の練習問題 | IDEA*IDEAの次の問題をやってみた。
次は

  • 現在時刻にあわせてやる気のでるメッセージを出力(例:もうすぐランチ!がんばれ!)。


だな。

case Time.now.hour
when 7..11
puts "朝ですよ"
when 12..15
puts "昼だよ"
when 16..18
puts "もう夕方だよ"
when 19..21
puts "晩御飯の時間だよ"
when 22..24
puts "ふぁ~おやすみなさい"
else
puts "こんな時間になにしてるの?!"
end


こんなんで、いいのか?!
なんか前回より簡単な気が。。。

2008年11月9日日曜日

10の練習問題 その01

最近は Rails を学習する前に Ruby を学習しようと考えていて、
新しくプログラミング言語を覚えたいときに行うべき10の練習問題 | IDEA*IDEA
の問題を Ruby でやっていこうかと。
  1. 「なんらかのカウントアップメッセージを1から100まで出すけど、3のときだけアホになる!(例:1万円!2万円!しゃ~ん万円!とか)」に変更。


ten=["",
"じゅ~",
"にじゅ~",
"さんじゅ~",
"よんじゅ~",
"ごじゅ~",
"ろくじゅ~",
"ななじゅ~",
"はちじゅ~",
"きゅ~じゅ~"]
one=["",
"いちっ",
"にっ",
"さんっ",
"よんっ",
"ごっ",
"ろくっ",
"ななっ",
"はちっ",
"きゅっ"]
(1..100).each do |i|
if (i % 3)==0||i.to_s=~/3/
num=i.to_s.rjust(2,"0")
print sprintf("%s%s",ten[num[0,1].to_i],one[num[1,1].to_i])
else
print i
end
puts "万円"
end

第1回「新しくプログラミング言語を覚えたいときに行うべき10の練習問題」をPHPでやってみた!
のルールにのっとっています。

  • 3の倍数のとき

  • 3がつくとき


最初は単純に3がつくときだけでやってた&3→"さんっ"に変えることしかやってなかったけど、"じゅ~さんっ"とか十の位の呼び方まで変える芸の細かさだったので右にならってみました。