セカイモンの裏側

★毎週木曜日更新★ 海外ショッピングサイト『セカイモン』のブログです。私たちスタッフの仕事風景や日々の出来事など、     “セカイモンの舞台裏”とも言える日常を綴っていきます。

ORMは無用の長物

無用の用と書こうとしたが、無用の用って役にたたなさそうで、役に立つっていう意味みたいなので、今回の意味とは違うようです。

kotowaza-allguide.com

本題のORMがなぜ不要かというと、ORMのメリットとデメリットを記載しました。

 

メリット

1、SQLがわからなくてもDBからデータを引っ張ってこれる

2、SQLインジェクションからORMで防げる

3、DBに関係なく同じコードで利用できる

4、バリデーションをモデルを書く事で構成が楽になる

 

デメリット

1、各フレームワークによって記述が違う

2、じゃぁこれって一体なんのSQLの実行??っていうのが直感でわからず、

DB::getQueryLogで確認しないと実際のSQLがわかりずらいって事がよくある

3、複雑なクエリに対応していない。またはいちいち調査しないといけない。

 

メリット1のSQLがわからなくてもDBからデータを引っ張ってこれるっていうメリットをよく聞くけど、そもそもプログラマーやっててSQLかけないなんてありえないというかプログラマーとして失格なんで メリットはほぼなし

 

メリット2ORMで記述している限りSQLインジェクションは防げます。

ただ、rawクエリでもplaceholderで防ぐ事ができます。 以下に例

$results = DB::select( DB::raw("SELECT * FROM some_table WHERE some_col = :somevariable"), array(
   'somevariable' => $someVariable,
 ));

なのでこれもメリットなし。

 

メリット3はDBがpostgresだろうがmysqlだろうが関係なくコードを書く事ができるという事ですが、基本的にSQLほぼDB一緒なんでこれもメリット薄 という事で

 

メリット4は過去にORMを崇拝してた事があった一番の要因です。Laravelでいうとardentというのを入れればtableを定義したmodelにバリデーションも追加できるので直感的にどのバリデーションが必要かどうかが簡単に記載できる 以下例

class Article extends Ardent {
//class Article extends Ardent {
/**
* The database table used by the model.
*
* @var string
*/
  protected $table = 't_article';
  public $timestamps = false;
  public static $rules = [
    'title' => 'required|between:1,500|',
    'body' => 'required|between:1,1000000|',
    'img' => 'between:1,1000000|',
  ];

}

コントローラで

DB::table('m_article')->insert(
array(
'name' => $_POST['title']
,'draft_name' => $_POST['title']
,'category_id' => $_POST['category_id']
,'created_at' => date("Y-m-d H:i:s")
,'updated_at' => date("Y-m-d H:i:s")
,'order_num' => $_POST['order_num']
,'draft_order_num' => $_POST['order_num']
,'full_txt' => $_POST['free_txt']
,'draft_full_txt' => $_POST['free_txt']
,'id' => $article_id
,'public' => 0
)
);

と書いても、もし文字列以上のバリデーションに引っかかるとexceptionに吐かれる。

自動でmodelで記載してるのでいちいちコントローラでバリデーションのコードを書かなくてすむ。なので、ORMはやっぱり必要と思っていました。

しかし

運用していくうちに割とあしかせになってる事がおおかった。「あれインサートできない??なぜ??あ、Modelのバリデーションで引っかかってた」という事が多かった。

あと、insertする部分を全てAJAXでpostするってなった場合はjavascriptでバリデーションするので結局JS部分でも記述が必要になった。

という2つの理由で結局使わない方がいいというのが今の判断です。

API専用のWebサービスとかであればいいかもしれないですが、バリデーションも全てモデルで結局補えないのでコントローラで書くって事に決めた方がわかりやすいかと思います。バリデーションをコントローラでモデルどっちでまとめるかっていうのも迷ってた時がありました。

detail.chiebukuro.yahoo.co.jp

今となってはFat Controllerの思想なので迷わずコントローラですね。

参考までにcodezineさんのメリット・デメリットです。

http://codezine.jp/article/detail/5858

メリット

メリット1と一緒でSQLを最小限にしたところでそれがメリットにはならない。

  • PDT(PHP Development Tools)やPHPEclipseなどの統合開発環境でメソッドの補完を行うことができるので、スペルミスやAPIを調べる手間が省ける

?? スペルミスはテーブル名とかのミスが多くてそれを防げるのであればいいけどそれは防げないかと。スペルミスがあっても実行してすぐにわかればいいかと。

  • 可搬性が上がる。データベース固有の振る舞いを吸収するので、別のデータベースに移行する際にビジネスロジックの変更を少なくできる

メリット3と一緒ですね。

デメリット

  • スキーマを変更するたびにORMクラスの再構築が必要になる場合がある
  • ORM自体を実行するオーバーヘッドが増える

 

symfonyとかであれば再構築しないときれいにORMクラスが作成されないとかはあったと覚えてます。kohanaとかは更新でORMはクラスを構築できるかと思います。

オーバーヘッドはコードが増えればそうなるかと思います。ないに越した事がないとなるとやっぱりFat Controllerが好きな理由です。

やっぱりSQLが直感で見れないのはわかりにくいわ〜。