#始めに
DBへの問い合わせ結果をHTML上に表示します
ORマッパーにAciveRerodは使いません、Sequelを使います
#やりたいこと
英次郎の辞書データをOracleDBに挿入する part2
http://qiita.com/triple4649/items/dc0fd2bb3cdbcd4a4bdb
で作った辞書データ(約33万レコード)に対してブラウザから入力された文字列を条件に該当データを取得し、取得したデータを画面に表示します
具体的には
のように入力文字列に対して前方一致で一致した単語を表示します
#実装
ここからは実装部分に移ります
##View
Ruby on Rails のルーティングについて WebAPIについてで使ったソースをそのまま流用します
##contorller
Ruby on Rails のルーティングについて WebAPIについてで使ったソースで、
sample_controller.rbの「SampleController#sayhelloasynpost」
の呼び出しをModelクラスに実装したクラスを呼び出すようにします
class SampleController< ApplicationController
protect_from_forgery :expect => ["create"]
def sayhello
@msgToNikkyusan = '293、hello!';
@msgToPerorisan = 'ペロリさん、hello!';
end
#初期表示で呼ばれるメソッド
def sayhelloToNyukkyusan
@msgToNikkyusan = '293、hello!';
end
#Ajaxから呼ばれるメソッド
def sayhelloasynpost
render text:Worddictionary.belongs(params[:name])
end
end
##Model
require されている"db"については後述します
SequelはSQLをべたで使ってもいいし、使わなくてもいいという設計は私のように
「ActiveRerodのモデル操作メソッドはいらない(⁼DBへの問い合わせは自前でSQLを実行したい)」
「O/Rマッパーは手軽に使いたい」
人には便利です
JavaでいうところのStreamAPIに相当する関数を使えば、DBの戻り値に対する編集も宣言的にかけループやIFがいらないので、コーディングが楽ちんです
ただし、ModelクラスでDBから受け取った値をContorller側の都合に合わせて編集していいかどうかはかなり微妙なところ。
まぁ、その場合も、modelクラスのメソッドにラムダ式を渡せる用意して、Contorllerの編集仕様をラムダ式に渡せるようにしてあげれば、汎用度は上がると思う
require "db"
class Worddictionary
def self.first(str)
result=DB.fetch("select WORD, SHORT_VER,WORD_LEVEL from WORD_DICTIONAY ")
.where(:search_word =>["#{str}"])
.first
return "単語{result[:word]} <br>
単語の意味:#{result[:short_ver]} <br>
単語レベル:#{result[:word_level]}#"
end
def self.count(str)
result=DB.fetch("
select word,count(*) as kensuu
from WORD_DICTIONAY
where search_word = '#{str}'
group by word"
).first
return "単語:#{str} 単語件数:#{result[:kensuu]}"
end
def self.belongs(str)
DB[:WORD_DICTIONAY]
.where{search_word.ilike "#{str}%"}
.all
.map{|m| "
-----------------------------
単語:#{m[:word]}
単語の意味:#{m[:short_ver]}
単語レベル:#{m[:word_level]}
-----------------------------" }
.reduce{|x,y|x+y}
end
end
##DB
libs配下にdb周りの設定を記載したrbファイルを置いています
簡単なアプリの例なので、コネクションの記述は結構適当です
SequelはJDBCのthin接続をサポートしているので、コネクション取得の記述が楽チンでした
require "sequel"
DB = Sequel.connect('jdbc:oracle:thin:triple/triple@//localhost:1521/triple_pb.co.jp')
##テーブル情報を表示する
def fetchUserTables
DB.fetch("select table_name from user_tables ")
.all do
|x|puts x
end
end
##gemファイル
Sequelがralisから使えるようにGemファイルに
gem 'sequel'
の一行を追加し、railsのカレントフォルダでコマンドラインからbundle installを実行した
Ralisにあまり詳しくないので、もっといいやり方があるかも
#最後に
Worddictionaryでブラウザから入力した値をそのままSQLの条件として埋め込んでいる。
これはSQLインジェクションというセキュリティホールになるので、SQLインジェクションが起こらないようになっているか、railsもしくはSequel側で対応しているか調べてみようと思う