Categories
open all | close allTags
パソコン | モデル | 名称 | 認証 | JustPosted | デュアル・コア | Aptana | CSRF | RESTful | 国際化 | ドキュメント | テスト | フォーム | Flash | アクセス制御 | rake | スキンエンジン | Migration | Subversion | タグSearch
シンプルな状態で試してみた
自己流のコードが入っていると,何が問題になっているのか分からなくなってしまうので,一回何もないアプリから始めて,ActiveRecord::Base.table_name_prefixだけを設定して
テストを実行してみました。
結果→×
やはりrakeがテスト用DBにデータをコピーするときにprefixを二重にしてしまいます。
こんなことでいいのか?>Rails
自分で修正できるものならしたいのですが,まだそこまでコードが分かりません。
テストの問題は
http://www.ruby-forum.com/topic/169とかにあるらしいことが分かってきました。
まだちゃんと理解していないけど,面倒そうだなあ…
set_table_nameとunit testとかで検索すると一杯でてくるので
既出のことのはずだけど,解決法がまとまっていないのは
いかがなものか,という気がします。
新たな問題──先に進まないよう
やっとテーブル名の問題が解決したので(と思って),今度はモデルのリレーションを設定してみました。この部分はscaffoldではテストできないので,Railsのテスト機能を使ってみることに。本を読むと,Rakeを使ったRailsのテスト機能ではテーブルをテスト用DBにコピーして使うとのこと。なるほど,それでテスト用DBは別の設定にしろと書いてあるわけです。新しくDBを作って実行してみました…
うまくいきません。テーブルがないと怒られます。
MySQL AdministratorでDBを見てみたところ,本来nucleus_itemなどとなるテーブル名が,nucleus_nucleus_itemなどとなっています。どうやら昨日の変更による副作用です。テーブルをコピーする際に,ActiveRecord::Base.table_name_prefixの設定を使って二重にプリフィクスを付けてしまったのでしょう。
しょうがないので,ActiveRecord::Base.table_name_prefixを使わず,プリフィクスを直打ちするという,なんともきたない方法で当座をしのぐことにしました。はぁ。
問題解決
方向性は合っていました。インスタンス・メソッドではなく,クラス・メソッドにしなきゃいけないことに気付いて解決。YAMLを使うところには行き着いていませんが,そこはちょっとしきいが高そうなので,とりあえずこれで満足です。ちょっとRubyらしいことをした気分(笑)。
module ActiveRecord
class Base
def self.set_base_name(basename)
@base_name = basename
end
def self.table_name
@@table_name_prefix + @base_name.to_s
end
end
end結局難航
テーブル名にプレフィクスを付ける件,environment.rbの中でActiveRecord::Base.table_name_prefixを設定すればいいと書いてあったので試したところ,見事に動きませんでした。いろいろ調べて分かったことはActiveRecord::Baseクラスの中で,モデルのクラス名からテーブル名を生成するtable_nameメソッドの中で,このプレフィクスが使われているということ。それに対して先日モデル・クラスの設定で行ったset_table_nameというのは,このメソッドをオーバーライドするものだった,ということです。オーバーライドしちゃっているから,ActiveRecord::Base.table_name_prefixが働かなかったわけです。
ActiveRecord::Baseとモデルの間に別のクラスを作って対処しようかと思ったのですが,そうするとAptanaでクラスを生成するたびに,そこを書き換えなければならず,メンテ的にかなりいやな感じ。Rubyでは存在しているクラスのメソッドを置き換えられるので,それで対処できないか考えました。
environment.rbの中でActiveRecord::Base.table_name_prefixを設定するのは同じですが,このほかに,
class ActiveRecord::Base
def set_base_name(name)
@base_name = name
end
def table_name
@@table_name_prefix + @base_name
end
end
といった記述を加え,モデル・クラスでは
set_base_name :item
などと書いてみました。しかしこれはset_base_nameがないというエラーになります。う~ん,environment.rbを先に見てくれないのか,それとも書き方の問題か。またストップしてしまいました。
PS. このブログのRSSを購読している人が何人かいるのですが,だれだろう。ちょっと気になります。
DRYの呪縛に会う
Railsの精神としてDRY(Don't Repeat Yourself)というのがあります。要は車輪の再発明はするな,ということですね。これがRailsを便利にしているのは確かですが,半面,僕のような初心者にとっては,どれが既に存在しているものなのかが分からず,苦労する面もあります。さらにRailsの場合,規約が多いので,どこでどうなっているのか分かりにくいという面もあるような。例えば,昨日からテーブルのプレフィクスをどうやって付けるのがいいのか,調べていたのですが,なかなか分かりませんでした。英語のフォーラムなども検索して,いくつか候補はでてきましたが,まだ試していないので,どれがいいのか分かりません。
あまり気にする必要はないのかもしれませんが,意外とラーニング・カーブは緩やかなのではないかという気がします。どこかでスレッショルドを超えると急に楽になるのでしょうけど。
Railsにちょっと進出(やっと)
DBの文字コード問題が解決したのでやっと先に進めます。まずはAptanaでアプリケーションを生成し,database.ymlを編集。移行したDBにアクセスするようにしました。注意したのはテーブル名を複数形にしない設定にしたこと。あと,テストモードのDBを別にしないといけないと注意書きが書いてありましたが,作るのが面倒なのでいまのところ一緒のものに。このあたりは問題が実際に起こってから考えます。
Railsはいろいろな「規約」を設けることで,プログラミングを楽にしていますが,実は今回のように既存のDBを使う場合,「規約」に合わせることができないため,いろいろと面倒なことが起こります。一からRailsで作るのと比べると倍くらい,気を使うところが多いのではないでしょうか。
次に,DBのテーブルにアクセスするための「モデル」を作っていきます。最初はモデルのクラスをただ作ればいいのかと思ったのですが,それだけでは動かないようです。generatorでモデルを作る必要がありました(このあたり,何がどう絡んで動いているのかは,知らなくてもいいのかもしれませんが,多分将来はきちんと理解しておく必要が出てくるでしょう)。
まずはアイテムのためのItemを生成。ここでもテーブルが規約に合っていないので,
set_primary_key: inumber
set_table_name: nucleus_item
と付ける必要があります。
とりあえず,scaffoldを使ってDBアクセスできるかどうか試そうとしたのですが,ジェネレータがDBがないとエラーを吐いてうまくいきません。CodeZineの記事を参考にコントローラを作り,scaffold: itemと書いてサーバーを起動。http://localhost/userにアクセスしたら,おお,ちゃんとnucleus_itemテーブルの内容が表示されました。
ただ,日本語が全部文字化けして?になっています。再びCodeZineの記事から文字設定をし(Layoutはまだ使っていないので不要),DBの文字設定もしました。多分DBのところが一番問題だったのではないかという気がします。これらの修正で,ちゃんと日本語でテーブルの内容を表示しました。
scaffoldには実用的な意味はあまり期待していないのですが,こうやってDBへのアクセスを簡単に確認できるのはありがたいことです。
というわけでRailsに踏み出したといっても,まだコードも何も書いていないのですが,一つ動くことはようやく確認できました。次はほかのテーブルも同じようにモデルを作っていき,リレーションの設定をしていくことになります。
ようやくスタート地点に立つ準備が
鬱陶しかったMySQLの文字化け問題,結局Nucleusで取ったバックアップをUTF-8に設定したローカルのMySQL(XAMPP上)でリストア。それをMySQL Administratorでバックアップし,InstantRailsの上のMySQLにリストアすることで文字化けなしのDBになりました。あー,めんどくさい。
こんなまだるっこしいことしなくていいのに,と思う人もいるでしょうが,XAMPPの環境やInstantRailsの環境をいじるのを避けようとすると,これくらいしか道がなくて。
それにしても将来ホスティングのDBでこの問題を解決しないといけなくなったら結構大変だなあ。
何か楽な手はないでしょうかねえ。
My First Ruby Program
結局仕事で必要になったCSVの処理プログラムを作ることにした。CSVを処理するライブラリがあったので,簡単にできそうだったというのがやっと飛び込んだ理由。
昨日ヘルプのWindows Help版をダウンロードしたのも気持ち的には大きい。やはりHelpは偉大だ。PHPもほとんどHelpで勉強したようなものだけど,これで高い文法本やライブラリ本を買わずに済んだ。
処理的には,HTTP使ってHTML取得したり,正規表現や文字列処理,例外処理も入って,わずか40行あまりながら,少し慣れた気がする。少なくともPerlの代わりにコマンドライン・ツールとして使うのはできそう。
慣れたツールというのは楽なもので
MixiAddDiaryのところをRubyで書いてみようかと思ったけど結局,ライブラリとかを調べるのが面倒なので,既に存在する
コードをいじるのがやっぱり一番楽だった。
仕事でちょっとテキスト処理をしないといけないのだけど,
これもローカルにサーバー立ててPHPで動かしてしまうのが
一番早く終わりそう。
本当はこういうところが新しいものにチャレンジするチャンス
なのだろうけど,やはり新しいものに踏み出すのは難しい。
特にライブラリがからむとそういう面が強くなる。