LoginSignup
3
4

More than 5 years have passed since last update.

Ruby on Rails DBへのアクセス

Last updated at Posted at 2017-07-30

始めに

DBへの問い合わせ結果をHTML上に表示します
ORマッパーにAciveRerodは使いません、Sequelを使います

やりたいこと

英次郎の辞書データをOracleDBに挿入する part2
http://qiita.com/triple4649/items/dc0fd2bb3cdbcd4a4bdb
で作った辞書データ(約33万レコード)に対してブラウザから入力された文字列を条件に該当データを取得し、取得したデータを画面に表示します
具体的には

image.png
で検索対象文字列をいれると

image.png

のように入力文字列に対して前方一致で一致した単語を表示します

実装

ここからは実装部分に移ります

View

Ruby on Rails のルーティングについて WebAPIについてで使ったソースをそのまま流用します

contorller

Ruby on Rails のルーティングについて WebAPIについてで使ったソースで、
sample_controller.rbの「SampleController#sayhelloasynpost」
の呼び出しをModelクラスに実装したクラスを呼び出すようにします

sample_controller.rb
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の編集仕様をラムダ式に渡せるようにしてあげれば、汎用度は上がると思う

worddictionary.rb
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接続をサポートしているので、コネクション取得の記述が楽チンでした

db.rb
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側で対応しているか調べてみようと思う

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4