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という別のクエリセットを作成することができる. これも気持ちいよね. クエリの実行のタイミングとか比較する場所は結構あるしー面白いところなんだけど….疲れちゃった…あはは….
Comments