2010年06月30日

Ruby on Rails With PostgreSQL 複数キーによるJOIN

JOINとは?


以前の記事をご覧下さい。

複数キーとは?


TABLE1とTABLE2を紐付けるものが、
TABLE1.id=TABLE2.TABLE1_idの1つである場合と、
TABLE1.id=TABLE2.TABLE1_idと
TABLE1.hoge_id = TABLE2.hoge_idの様に
複数で紐付ける場合が有ります。
この複数で紐付ける場合の事を複数キー(勝手にそう呼んでる)

環境


rails1.2.6
PostgreSQL8.3.5
script/console
TABLE1
TABLE2

使用方法


$ ruby script/console
Table1.find(:all,
:joins => "LEFT JOIN TABLE2 ON TABLE1.id = TABLE2.TABLE1_id " <<
      "AND TABLE1.hoge_id = TABLE2.hoge_id)

これでidとhoge_idの2つのキーによってTABLE1とTABLE2が結びつけられました。

自分ほとんどこういうの使わないんですが、includeではどうやってやるんだろぅか。。
posted by RicK at 16:36| Comment(0) | TrackBack(0) | 日記

2010年06月29日

Ruby 文字の削除

環境


ruby1.8.6
irb

指定した文字の削除


deleteメソッドとdelete!メソッドを使用します。
$ irb
hoge = "abcd"
hoge.delete("a")
=> "bcd"
hoge
=> "abcd"
hoge.delete("^a")
=> "a"
hoge
=> "abcd"
hoge.delete("a-c")
=> "d"
hoge
=> "abcd"

hoge = "abcd"
hoge.delete!("a")
=> "bcd"
hoge
=> "bcd"
hoge = "abcd"
hoge.delete("^a")
=> "a"
hoge
=> "a"
hoge = "abcd"
hoge.delete("a-c")
=> "d"
hoge
=> "d"

deleteは、非破壊的メソッド、
delete!は、破壊的メソッドとなります。
delete("a"):文字列から"a"を除きます。(aが2つ有れば2つ削除)
delete("^a"):文字列から"a"以外を除きます。
delete("a-c"):文字列から"abc"を除きます。
正規表現は使えませんのでご注意を

行末の文字削除


chopメソッドとchompメソッドを使用します。
$ irb
"abc\n".chop
=> "abc"
"abc\r\n".chop
=> "abc"
"abc".chop
=> "ab"

"abc\n".chomp
=> "abc"
"abc\r\n".chomp
=> "abc"
"abc".chomp
=> "abc"
"abc\r\n\r\n".chomp
=> "abc\n\r"
"abc\r\n\r\n".chomp("")
=> "abc"

chopメソッドは、文末の1文字を問答無用で削除します。
ただし、\r\nの場合は2文字削除します。
chompメソッドは、文末の1行の\nや\r\nだけを削除します。
引数を与えないと1つの\r\nだけですが、引数に""を与えてあげると
何個でも削除してくれます。

削除してくれるのはあくまで文末ですので、
"a\r\nb\r\nc\r\n".chomp
=> "a\r\nb\r\nc"

こんな風に途中の改行は削除されません。

引数を空白以外にしてみると
"abc,,".chomp(",")
=> "abc,"

こんな風に,が削除されます。
けど1個だけです。

ちなみにchopもchompもchop!とchomp!が有ります。
posted by RicK at 16:32| Comment(0) | TrackBack(0) | 日記

2010年06月28日

Ruby 文字列の取得・検索

環境


ruby1.8.6
irb

文字列の取得


文字列の取得には、[]演算子を使用します。
$ irb
hoge = "abc def ghi jk"
hoge[1,4]
=> "bc d"
hoge[10,5]
=> "i jk"
hoge[-3,2]
=> " j"
hoge[2..4]
=> "c d"
hoge[2...-2]
=> "c def ghi j"

さて、わかりましたか?
hoge[1,4] :indexの1から4つを取り出す。
hoge[10,5]:indexの10から5つを取り出す、ただし先がない場合は省略。
hoge[-3,2]:indexの-3つまり後ろから3つ目から2つを取り出す。
hoge[2..4]:indexの2からindexの4まで取り出す。(4つ取り出すではないので注意)
hoge[2...-2]:indexの2からindexの-2の一つ手前つまり後ろから3つ目まで取り出す。

文字列の検索


$ irb
hoge = "abcdefbc"
hoge.index("bc")
=> 1
hoge.index("bc",2)
=> 6
hoge.index(/b./,2)
=> 6

hoge.index("bc"):文字列中最初のbcの先頭のindexを返します。
hoge.index("bc",2):文字列中のindex2以降で最初のbcのindexを返します。
hoge.index(/b./,2):文字列中のindex2以降で正規表現にあてはまるindexを返します。
posted by RicK at 16:30| Comment(0) | TrackBack(0) | 日記

2010年06月25日

Ruby ヒアドキュメント

ヒアドキュメントとは?


複数業に渡る長い文字列を作成するのに使われます。

環境


ruby1.8.6
irb

使用方法


$ irb
x = >>END
hoge
boge
END
puts x
=> "hoge\boge\n"

x = >>END

ここのENDの前と最後のENDの前には空白も禁止です。

$ irb
x = >>-END
hoge
boge
 END
puts x
=> "hoge\boge\n"

最初のENDの前に-を入れる事によって、
最後のENDをインデントする事を許可します。

$ irb
hoge = 123
x = >>END
#{hoge}
boge
END
puts x
=> "123\boge\n"

hoge = 123
x = >>'END'
#{hoge}
boge
END
puts x
=> "\#{hoge}\boge\n"

ヒアドキュメントのデフォルトはダブルクォートで囲まれていると
同じこのなので、#{}が使用可能ですが、
使用したくないのであれば、最初のENDをシングルクォートで囲めばよいです。
posted by RicK at 14:04| Comment(0) | TrackBack(0) | 日記

2010年06月24日

Ruby on Rails with DB ランダム検索

ランダム検索とは?


まぁ言うまでもなくランダムに値を取ってくる事ですね。
前まではrand()を使用していました。
DBを使用しないランダムはこれでいいのですが、
これを知らなかったばっかりにDB検索でもrand()を使用していました。。。

環境


rails1.2.6
app/controllers/hoges_controllers.rb

rand()


まず以前の方法から、
・あるテーブルの全レコードからランダムで1件抜き出して表示したい。
$ vi hoges_controllers.rb
def hoge
 @hoges = Hoge.find(:all)
 random = @hoges[rand(@hoges.length)]
end

全部取り出してからわざわざ1件とりだすとか面倒な上に
レコードの数が増えれば増える程遅くなる訳ですよ。

RANDOM()、RAND()


はてさて、これを使用すると、
$ vi hoges_controllers.rb
def hoge
 @hoges = Hoge.find(:all, :order => 'RANDOM()', :limit => 1)
end

はい!これで終了!!
1行じゃん!全部取り出す必要ないじゃん!!!ってなわけです。
しかも、
$ vi hoges_controllers.rb
def hoge(limit = 1)
 @hoges = Hoge.find(:all, :order => 'RANDOM()', :limit => limit)
end

引数にリミットを付ける事でランダムで取り出せる数を簡単に決める事ができます。
いや〜すばらしいですね。。

あ、なんでRANDOM()とRAND()があるかというと
PostgreSQLはRANDOM()で
MySQLはRAND()なのでご注意を。

・・・もちょっとDBの勉強しなきゃだなぁ。。
posted by RicK at 17:56| Comment(0) | TrackBack(0) | 日記

2010年06月23日

Ruby on Rails メソッド定義

メソッドとは?


クラスについている機能というかクラスを使う為の機能というかそういった感じですかねぇ?

環境


rails1.2.6
app/controllers/hoges_controller.rb

使用方法


$ vi hoges_controller.rb
def sum(a,b)
 a+b
end

def hoge
 sum(1,2)
end
=%gt; 3

メソッドはこんな感じで作成します。
$ vi hoges_controller.rb
def sum(a,b=10)
 a+b
end

def hoge
 sum(20)
 => 30
 sum(1,1)
 => 2
end

こんな風にデフォルト値をセットしておけば、
第2引数が空でもデフォルト値を自動的にセットしてくれます。

$ vi hoges_controller.rb
def sum(*a)
 sum = 0
 a.each do |b|
   sum += b
 end
 return sum
end

def hoge
 sum(1,2,3,4,5)
end
=> 15

このように引数に*を付けると配列として渡されます。
ただし、*は最後の引数につけなければなりません。
posted by RicK at 14:24| Comment(0) | TrackBack(0) | 日記

2010年06月22日

Ruby on Rails 例外処理 begin

例外処理とは?


なにかエラーが発生した場合の処理です。
以前軽く書きましたね。

環境


Rails1.2.6
app/controllers/hoge_controller.rb

begin


$ vi hoge_controller.rb
def hoge
 begin
  例外が起きそうな通常処理
 rescue
  例外が起きた場合の処理
 else
  例外が発生しなかった場合の処理
 ensure
  例外が発生してもしなくても行う処理
 end
end

# 基本上記のような感じですね。
def hoge
 begin
  raise "例外発生"
 rescue => e
  logger.error e.class.name
  logger.error e.message
 end
end
=> RuntimeError
例外発生

2つめの例では例外が起きたオブジェクトのクラス名とメッセージを表示しています。
backtraceで発生した場所も出す事が可能です。

rescueの後が=> eですが、これは、
rescue StandardError => e というのが省略された形です。
省略された場合StandardErrorが呼ばれますので、
StandardErrorのサブクラスでないエラーをキャッチしたい場合は、
必ず書かなくては行けません。

以前とたいして書いた事変わらないかもですが、少し詳しく書いてみました。
posted by RicK at 15:47| Comment(0) | TrackBack(0) | 日記

2010年06月21日

Ruby イテレーター

イテレーターとは?


繰り返しのtimesやeachなどです。

環境


ruby1.8.6
irb

times


$ irb
3.times do |i|
 puts i + 1
end
=> 1
2
3

3回繰り返してくれました。
単純に決まった回数回すだけの時に便利です。

each


配列
$ irb
hoges = ["1","2","3"]
hoge.each do |hoge|
 puts hoge
end
=> "1"
"2"
"3"

配列の値の数だけ繰り返してくれます。

ハッシュ
$ irb
hoges = {:name => "hoge", :age => 20}
hoges.each do |k,v|
 puts "#{k}=%gt;#{v}"
end
=> name => hoge
age => 20

ハッシュの値の数だけ繰り返して、キーと値の両方を取り出してくれます。

for


配列
$ irb
hoge = [[1,2],[3,4]]
for x,y in hoge
 puts [x,y]
end
=> [1,2]
[3,4]


ハッシュ
$ irb
hoge = {1=>2,3=>4}
for x,y in hoge
 puts [x,y]
end
=> [1,2]
[3,4]

まぁほぼeachと一緒ですね。
rubyやrailsでは、ほとんどfor文は使う事はないと思います。
eachでやってしまうのがほとんどですからね。
posted by RicK at 15:15| Comment(0) | TrackBack(0) | 日記

2010年06月18日

Ruby 演算子

演算子とは?


+とか-とかです。

環境


ruby 1.8.6
irb

普通の+とか>とか説明してもなんなんで、
特殊という程でもないですが、普段使わないような演算子のご説明

ちょっと特殊な演算子


** : べき乗
$ irb
2 ** 3
=> 8

2 * 2 * 2ですね。

=== : 同値(case文の一致判定はこれを使用しています)
この===はくせ者で、普段は==と同じ働きをするのですが、
サブクラスなどで再定義されていると変わってしまうのです。
では、再定義はどこで?
Module : kind_of?を呼んでいる
Proc : callの別名
Range : include?を呼んでいる
Regexp : =~やmatchとほぼ同義
難しいです。

<=> : 大小比較
$ irb
1 <=> 2
=> -1
1 <=> 1
=> 0
2 <=> 1
=> 1

左が大きければ+1、右が大きければ-1、等しければ0となります。
Array.sortの仕組みもこの大小比較で行われています。

.. : 範囲演算子(範囲含む)
$ irb
i=0
1..3.times do
 puts i
 i += 1
end
=>0
1
2

3回ループしました。
1,2,3の配列の中身を取り出したりするのに使用したりしますね。

... : 範囲演算子(範囲含まない)
$ irb
i=0
1...3.times do
 puts i
 i += 1
end
=>0
1

2回ループしました。
..とは違い最後の1回は含まれない訳ですね。

? : : 条件演算子
三項演算子ともいますね。
言うなれば1行のif文ってところでしょうか。
$ irb
5 > 2 ? "真" : "偽"
=> "真"

?前の条件文にあてはまる場合:の左が実行され、偽の場合:の右が実行されます。

演算子の優先度


演算子には優先度が存在します。
まぁ数学の+より*のほうが先に計算するといったのと同じです。
演算子もだいたいそれにあてはまって、
+より* のほうが優先されます。
こまかく書くのも面倒なのですが、
** > * > + > <= > && > .. > = > and

こんな感じで覚えておけばいいかな?
posted by RicK at 14:46| Comment(0) | TrackBack(0) | 日記

2010年06月17日

Ruby on Rails date_select TypeError can't convert Symbol into StringCommentsAdd Star

data_selectとは?


以前紹介していますのでそちらをごらんください。

環境


rails2.2.2

can't convert Symbol into StringCommentsAdd Star


data_selectを使用するとなぜかこのエラーが出る様になりました。
どうやらi18nの
config.i18n.default_locale = :ja

こいつが悪いらしいです。

解決策1


$ vi ../lib/action_view/helpers/date_helper.rb
def translated_date_order
 begin
  I18n.translate(:'date.order', :local => @options[:locale]) || []
 end
end

// 上記を下記に書き換え
def translated_date_order
 begin
  order = I18n.translate(:'date.order', :locale => @options[:locale])
  if order.respond_to?(:to_ary)
   order
  else
   [:year, :month, :day]
  end
 end
end

ライブラリーを書き換えるとかなんかやな感じですけどね。
オーバーライドしようと思ったらなぜかできなかった。。。
まぁきっとなんかまちがっていたんだろぅ。

解決策2


$ vi config/locales/ja.yml
ja:
 date:
  formats:
   default: "%Y年%m月%d日"
   abbr_default: "%Y-%m-%d"
   short: "%b%d日"
   long: "%Y年%b%d日"
  day_names: [日曜日, 月曜日, 火曜日, 水曜日, 木曜日, 金曜日, 土曜日]
  abbr_day_names: [日, 月, 火, 水, 木, 金, 土]
  month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
  abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
  order: [ :year, :month, :day ]

これで解決。
どうやら日本語のロケール情報がない為におこられていたようです。
posted by RicK at 12:17| Comment(0) | TrackBack(0) | 日記