Rails と Django 比較 ~テーブルの操作~

さてさて,せっかくBBSのモデル(BBSテーブル)を作成したので,レコードを追加したりしてみようと思います.

Django, Railsは,モデルクラスがデータベースのテーブルを表現し,クラスのインスタンスがレコードを表現する. それだけを頭に入れて,まずは色々やってみようと思う!! こんなものは動かしてナンボでしょ!?

■ Rails

□ オブジェクトの生成 俺のようなアホだと,オブジェクト生成と聞くと単なるインスタンス化すりゃいいのか?なんて思っちゃったりもする…データベースとの関係を忘れてしまっている…. ちゃんと最初の述べたコトを頭に入れてあれば問題ないはず. つまり,新しいBBSテーブルに新しいレコードを生成するってことですわっ!!

オブジェクトを作るには,newメソッドを使う. (メソッドっていう表現でいいのか? rubyの通常のインスタンス化させるときの命令です.実際は initialize(PHPでいう__construct)が引数を受け取れるメソッドになっている.)

bbs = Bbs.new(:user_id => 1,
    :title   => "TEST TITLE",
    :message => "TEST MESSAGE")

もちろん,タイトルやメッセージはオブジェクトを作成してから設定することもできる.

bbs = Bbs.new
bbs.title   = "TEST TITLE"
bbs.message = "TEST MESSAGE"

この時点では,まだDBにはレコードは追加されてないです.最後にsaveメソッドを実行することでDBに書き込まれます.

bbs.save
mysql> select * from bbs;
+----+---------+------------+--------------+---------------------+---------------------+-------------+
| id | user_id | title      | message      | created_at          | updated_at          | delete_flag |
+----+---------+------------+--------------+---------------------+---------------------+-------------+
|  1 |       1 | TEST TITLE | TEST MESSAGE | 2007-06-30 10:35:12 | 2007-06-30 10:35:12 |           0 |
+----+---------+------------+--------------+---------------------+---------------------+-------------+

また,createメソッドを使ってオブジェクトを生成することもできる. これは,createメソッドを実行すると save まで行ってくれる. (createメソッドの中で,new(インスタンス化)してsaveを実行している. ん!? createメソッドってPHPでいう staticメソッドなのか?…やばっ…,ネイティブのrubyを知らないでやっていることがモロバレ!!! ちゃんと勉強しないとまずいですね.こういう俺のようなヤツが世にヒドイソースを散らすことになるのだろう(微笑))

Bbs.create(:user_id => 1,
           :title   => "TEST TITLE",
           :message => "TEST MESSAGE")

□ オブジェクトの取得 今度は,上記で登録したレコード(オブジェクト)を取得する.

検索するには,findメソッドを使う.(他にも色んなメソッドがあります.)

IDによる検索例

bbs = Bbs.find(1)
bbs.title     # TEST TITLE
bbs.message # TEST MESSAGE

もし見つからない場合は,「ActiveRecord::RecordNotFound」例外が発生する.

find :firstを使ったタイトルとメッセージによる検索例

bbs = Bbs.find(:first,
               :conditions => ["title = ? AND message = ?", "TEST TITLE", "TEST MESSAGE"])

もし見つからない場合は,「nil」が返ってくる.

find :allを使った対応するオブジェクトの全取得

bbs = Bbs.find(:all,
               :conditions => ["delete_flag = ?", false],
               :order => "updated_at DESC",
               :limit => 10)

もし見つからない場合は,「[]」が返ってくる.

□ オブジェクトの更新 単純に1度オブジェクトを取得し,変更箇所書き換えsaveする. たとえば,ID=1のタイトルを「DEMO TITLE」に変更する場合,

bbs = Bbs.find(1)
bbs.title = "DEMO TITLE"
bbs.save
mysql> select * from bbs;
+----+---------+------------+--------------+---------------------+---------------------+-------------+
| id | user_id | title      | message      | created_at          | updated_at          | delete_flag |
+----+---------+------------+--------------+---------------------+---------------------+-------------+
|  1 |       1 | DEMO TITLE | TEST MESSAGE | 2007-06-30 10:35:12 | 2007-06-30 11:00:56 |           0 |
+----+---------+------------+--------------+---------------------+---------------------+-------------+

ちゃんと変更ができていて,かつ更新日も変更されている. しかし,あまりこの方法は取らないでしょうね….複数の項目の変更する場合は大変だし,saveなんて処理するのも面倒だしさ,だもんで,update_attributesメソッドを使う.

bbs = Bbs.find(1)
if bbs.update_attributes(:title => "DEMO TITLE")
  // 成功処理
else
  // エラー処理
end

このメソッドは成功するとtrueが返ってくるので,このようにif文を使ってアプリを作っていくのでしょう.

■ Django

□ オブジェクトの生成 Bbsモデルクラスをimportして,Bbsモデルクラスのインスタンスを生成し,save()メソッドでデータベースに保存する.

from django.http import HttpResponse

bbs = Bbs(user_id = 1,
          title = "TEST TITLE",
          message = "TEST MESSAGE")
bbs.save()

> select * from bbs_bbs;
+----+---------+------------+--------------+---------------------+---------------------+-------------+
| id | user_id | title      | message      | create_time         | update_time         | delete_flag |
+----+---------+------------+--------------+---------------------+---------------------+-------------+
|  1 |       1 | TEST TITLE | TEST MESSAGE | 2007-06-30 12:00:00 | 2007-06-30 12:00:00 |           0 |
+----+---------+------------+--------------+---------------------+---------------------+-------------+

railsと同様,save()メソッドを実行して初めて,データベースに保存される. もちろん,タイトルやメッセージはインスタンスを作成してから設定することもできる.

from django.http import HttpResponse

bbs = Bbs()
bbs.user_id = 1
bbs.title   = "TEST TITLE"
bbs.message = "TEST MESSAGE"
bbs.save()

また,create()メソッドを使ってsave()まで行う.railsと同じですね!

from django.http import HttpResponse

Bbs.objects.create(user_id = 1,
                   title   = "TEST TITLE",
                   message = "TEST MESSAGE")

objectsって突然出てきましたがー次に簡単に説明します.

□ オブジェクトの取得 オブジェクトを取得するには,モデルクラスのマネジャ(Manager)を使ってクエリセット(QuerySet)を構築する. クエリセットはデータベース上にあるオブジェクトの集まりを表現している. また,このマネジャはクラスに最低1つのマネジャがあり,デフォルトではobjectsという名前がついている. クエリを構築するには,filter()やexclude()を主に使う. (railsで言うfind()かと思うとーそれは間違い!! railsで言うfind()に近いのはget()になるでしょう.)

IDによる検索例

bbs = Bbs.objects.filter(id=1)

このとき得られた結果はクエリセットというものであり,けしてDB取得結果ではない.つまりbbs.titleなんてしてもエラーが 発生する. では,どんな時点でクエリが実行されるのかというと,クエリセットはfor文(イテレーション可能)などの操作を行った初めに実行される.

クエリ結果を返さず,DBの取得結果を返す場合は,

bbs = Bbs.objects.get(id=1)
bbs.title    # TEST TITLE
bbs.message  # TEST MESSAGE

もし見つからない場合は,DoesNotExist 例外を発生する.

タイトルとメッセージによる検索例

bbs_list = Bbs.objects.filter(title   = "TEST TITLE",
                                  message = "TEST MESSAG")

railsのfind firstと結果を合わせるとすると,下記のように取得数を指定するべきかな!?

bbs = Bbs.objects.filter(title   = "TEST TITLE",
                             message = "TEST MESSAG")[:1]

[:1]は,SQLでいうLIMIT句のLIMIT 1を表現している. ちなみに,[:10 :25] OFFSET 10 LIMIT 15 という意味.

全てのオブジェクトの取得

bbs_list = Bbs.objects.all().order_by('-update_time')[:10]

order_by('-update_time')は,ORDER BY update_time DESC を意味する.

□ オブジェクトの更新 単純に1度オブジェクトを取得し,変更箇所書き換えsaveする. たとえば,ID=1のタイトルを「DEMO TITLE」に変更する場合,

bbs = Bbs.(1)
bbs.title = "DEMO TITLE"
bbs.save

> select * from bbs_bbs;
+----+---------+------------+--------------+---------------------+---------------------+-------------+
| id | user_id | title      | message      | create_time         | update_time         | delete_flag |
+----+---------+------------+--------------+---------------------+---------------------+-------------+
|  1 |       1 | DEMO TITLE | TEST MESSAGE | 2007-06-30 12:00:00 | 2007-06-30 12:30:00 |           0 |
+----+---------+------------+--------------+---------------------+---------------------+-------------+

railsのようなsave() 一緒に実行してくれるやつがあると思うのですが…. ちょっとどれかわからなかったのでー改めて書きます(笑)(汗)

∞ ENDLESS THINK ∞ いやぁ 0単なる1つのテーブルをやるだけなのにーこうやって書いてくと面倒やわぁ 0.本当はリレーション(railsではアソシエーション)を試してみたかったのに….

今回,自分的考えをねー図に書いたりして説明したいコトがあるんですがー難しくてね….図に表すのも面倒だけど 0図に表現するのもチト難しい.

簡単に,今回思ったことを述べるとぉ 0. railsとDjangoを比べるとーやっぱRailsの方がわかりやすいかなぁ 0と思っちゃう!! でもrailsの condition の設定方法はチト面倒くさい!! だけどーDjangoの方余計面倒くさい!? それは覚えることがrailsに比べると多いかも….最初「objects」ってなんだよ!! こんなモン毎回書かせるなっ!!なんて思っておりました.でも,Djangoというフレームワークを作成した開発者のこだわりみたいなものが見えてきてーちょっと考えを改めましたよ☆

どうもー彼等はテーブル間の操作とレコードの操作を分離したかったと….だからレコードを操作しようとするとー「objects」というマネジャを通してじゃないとー行えない.(実はこれをうまく図に書いて説明したいんだけど…できなかった.また,そこに適当に足を突っ込むとー余計疑問がでてきてしまうのでね…) これがわかるとー「ほほー,いいねぇ 0納得納得」となるよね.

また,今回触れませんでしたがーDjangoのクエリセットというのがー再利用という表現でいいのかなぁ 0. Aというクエリセットが,A1 = A.filter(X), A2 = A.filter(Y) とすることでAのクエリセットを利用して,A1とA2という別のクエリセットを作成することができる. これも気持ちいよね. クエリの実行のタイミングとか比較する場所は結構あるしー面白いところなんだけど….疲れちゃった…あはは….

[RubyonRails] [Django]

2007/07/01 15:00 | Comments(0)

Comments

Comment Form