DataMapperを教えておじいさん
Ruby初心者です。
DataMapperとやらを使ってみているわけですが。
とにかく、情報が少なくて困ってしまいます。例えば、複数の LIKE 条件をつなぐときとか、どうすればいいの?
class Repo #例えばこんなクラスがあるとする include DataMapper::Resource property :id, Serial property :body, String end
普通のLIKE節の作成の仕方はこうなる。
Repo.all('body.like' => '%test%') #=> SELECT * FROM repos WHERE body LIKE '%test%';
または、シンボルで書くこともできる。
Repo.all(:body.like => '%here%') #=> SELECT * FROM repos WHERE body LIKE '%here%';
でも、複数のLIKE節をつなげる方法がいまいちわからない。そこで試してみた。
まずは配列。
Repo.all('body.like' => ['%test%', '%here%']) #=> SELECT * FROM repos WHERE body LIKE '%test%%here%';
失敗。
じゃあ羅列。
Repo.all('body.like' => '%test%', 'body.like' => '%here%') #=> SELECT * FROM repos WHERE body LIKE '%here%';
これも失敗。
ところが、こんな風にチェーンさせるとうまくいく。
Repo.all('body.like' => '%test%') + Repo.all('body.like' => '%here%') #=> SELECT * FROM repos WHERE body LIKE '%test%' OR body LIKE '%here%';
でも、確かにうまくいくのだけれど、プログラムに組み込むのはどうすればいいんだろう。「+」なんか使われたら、文字列の連結になっちゃうのでエラーになりそうだ。思いつく方法で検索フォームから検索語が入力されたらLIKE検索で結果を返すプログラムを作成してみる。
search_options = [] params[:keyword].gsub(' ', '').strip.split([\s]).each do |keyword| search_options << "Post.all('body.like' => '%#{keyword}%')" end eval_str = search_options.join(' + ') #まさか!? @repos = eval eval_str #な、なんと!!
よし、エスケープも用意するか。
def escape_shell_cmd keyword keyword.gsub!(/(["'#&;`|*?~<>^()\[\]{}$\\\x0A\xFF])/) { "\\" + $1 } end
うーん、どんどん間違った方向に進んでしまう。なんか、一般的なやり方っていうのがあって、こちらがそれを知らないだけなんだと思うんだけど、これ以上進むのは危険すぎるので調べることにする。
Comments
[…] This post was mentioned on Twitter by 超電磁ねこきっく. 超電磁ねこきっく said: "Ruby初心者です。 DataMapperとやらを使ってみているわけですが。 とにかく、情報が少なくて困ってしまいます。" http://selfkleptomaniac.org/archives/1458 […]
@repos = params[:keyword].split(/[\s ]+/).
map {|keyword| Repo.all(‘body.like’ => “%#{keyword}%”)}.inject(:+)
ほ、ほんまや、できとる!
ありがとうございます。