modelの追加
というワケで、昨日の続きをやる。今日は、「つぶやき」アプリを改修してみよう(前編) − @ITの内容を、3rdRailを使わないでコマンドラインで実施。
hitokotoの編集
昨日の時点で一点、忘れていた。3rdRailでモデル作成の際に、hitokotoに「必須」のチェックを入れているのだが、おそらく、それに対応するのが、これ。
% cat app/models/hitokoto.rb class Hitokoto < ActiveRecord::Base validates_presence_of :hitokoto end
app/models/hitokoto.rb に、「validates_presence_of :hitokoto」を追加する。
modelの追加: user
userモデルを追加する。「つぶやき」アプリを改修してみよう(前編) − @ITによると、気になることが書いてある。
今回は「生成されたリソースのスカフォルドを作成する」チェックを外しておくこととします
「つぶやき」アプリを改修してみよう(前編) − @IT
要するに、./script/generate scaffoldを使わないということだと思うんだけど、さて。
% ./script/generate --help Usage: ./script/generate generator [options] [args] .....(中略)... Installed Generators Builtin: controller, helper, integration_test, mailer, metal, migration, model, observer, performance_test, plugin, resource, scaffold, session_migration .....(以下略)...
このhelpを見て、何をすべきか分かる人は居ない気がする。やっぱり、railsに関して一通り説明してある本を買うべきだろうか?
modelを追加するけど、scaffoldじゃないという観点で考えると、ここで指定すべきoptionはおそらくmodelかresource。違いを知るには、sourceを見るか、、、と思ったけど、どのsourceを見れば良いのかさっぱり分からず断念。両方試してみることにした。
% ./script/generate model user name:string exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/user.rb create test/unit/user_test.rb create test/fixtures/users.yml exists db/migrate create db/migrate/20090501102445_create_users.rb % ./script/generate resource user name:string exists app/models/ exists app/controllers/ exists app/helpers/ create app/views/users exists test/functional/ exists test/unit/ exists test/unit/helpers/ dependency model exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/user.rb create test/unit/user_test.rb create test/fixtures/users.yml exists db/migrate create db/migrate/20090501103445_create_users.rb create app/controllers/users_controller.rb create test/functional/users_controller_test.rb create app/helpers/users_helper.rb create test/unit/helpers/users_helper_test.rb route map.resources :users
自動生成されるファイルの構成から考えると、ここで使うべきoptionはmodelではなくresourceなんだろうな、と、推測。そして、生成されたuser.rbにはhitokoto.rb同様に「validates_presence_of :name」を追加しておく。
% cat app/models/user.rb class User < ActiveRecord::Base validates_presence_of :name end
Hitokotoモデルへの属性追加
続いて、HitokotoモデルがUserに属すことができるようにHitokotoモデルを改修しましょう。Hitokotoモデルから見て、どの Userに属しているかが分かればよいので、Userへの関連IDが必要になります。そこで、マイグレーション機能を使用して、Hitokotoモデルの属性としてUserモデルへの関連IDを追加します。
「つぶやき」アプリを改修してみよう(前編) − @IT
これに対応する。やっぱり、./script/generateで生成できるんだろうか?試しにやってみる。
% ./script/generate migration AddUserIdToHitokotos user_id:integer exists db/migrate create db/migrate/20090501105327_add_user_id_to_hitokotos.rb % cat db/migrate/20090501105327_add_user_id_to_hitokotos.rb class AddUserIdToHitokotos < ActiveRecord::Migration def self.up add_column :hitokotos, :user_id, :integer end def self.down remove_column :hitokotos, :user_id end end
雛型はできたっぽいので、「つぶやき」アプリを改修してみよう(前編) − @ITに書かれている通りに、追記する。
% cat db/migrate/20090501105327_add_user_to_hitokotos.rb class AddUserIdToHitokotos < ActiveRecord::Migration def self.up add_column :hitokotos, :user_id, :integer, :null => false, :default => 0 end def self.down remove_column :hitokotos, :user_id end end
ここで、DBのmigrationをしておく。
% rake db:migrate (in /Users/fukuit/Projects/tsubuyaki) == CreateUsers: migrating ==================================================== -- create_table(:users) -> 0.0022s == CreateUsers: migrated (0.0025s) =========================================== == AddUserIdToHitokotos: migrating =========================================== -- add_column(:hitokotos, :user_id, :integer) -> 0.0012s == AddUserIdToHitokotos: migrated (0.0015s) ==================================
unit test
この後、「つぶやき」アプリを改修してみよう(前編) − @ITでは、unit testのためのコード作成が続く。
test/fixtures/hitokotos.yml、test/fixtures/users.yml、test/unit/user_test.rb、test/unit/hitokoto_test.rbのファイルを「つぶやき」アプリを改修してみよう(前編) − @ITのように作成してから、テスト用のDBを作成する。
% rake db:test:prepare (in /Users/fukuit/Projects/tsubuyaki)
railsでは、どうやってunit testを実施するのか?rakeで何かコマンドを入力するんだろうなぁ。例えば上述のように、DBに対してテスト用のデータを準備するのが、「rake db:test:prepare」だっていうことは、rakeのoptionは英語っぽく複数の単語を「:」で繋げば良さそうだ。まずは、テストをすることを指示して、それが結合テストじゃなくてunitだってことを指示すれば良いはず。というワケで、当てずっぽうにやってみる、それらしい結果が表示された。
% rake test:unit (in /Users/fukuit/Projects/tsubuyaki) rake aborted! Don't know how to build task 'test:unit' (See full trace by running task with --trace) % rake test:units (in /Users/fukuit/Projects/tsubuyaki) /usr/bin/ruby -I"/Users/fukuit/Projects/tsubuyaki/lib" -I"/Users/fukuit/Projects/tsubuyaki/test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/unit/helpers/users_helper_test.rb" "test/unit/helpers/hitokotos_helper_test.rb" "test/unit/user_test.rb" "test/unit/hitokoto_test.rb" Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader Started EE Finished in 0.058168 seconds. 1) Error: test_Hitokotoが属すUserを取得できる(HitokotoTest): NoMethodError: undefined method `user' for #<Hitokoto:0xb7d2ae58> /test/unit/hitokoto_test.rb:6:in `test_Hitokotoが属すUserを取得できる' 2) Error: test_Userに属すHitokotoを取得できる(UserTest): NoMethodError: undefined method `hitokotos' for #<User:0xb7d1344c> /test/unit/user_test.rb:6:in `test_Userに属すHitokotoを取得できる' 2 tests, 0 assertions, 0 failures, 2 errors rake aborted! Command failed with status (1): [/usr/bin/ruby -I"/Users/fukuit/Projects/ts...] (See full trace by running task with --trace)
どうやら「rake test:units」が正しいようだ。複数形なのね。
コードの修正
unit testの結果を受けて、「つぶやき」アプリを改修してみよう(前編) − @ITのように、app/models/hitokoto.rbとapp/models/user.rbを修正した上で、再びunit testを実行する。
% rake test:units ....(中略)... Started ... Finished in 0.061379 seconds. 2 tests, 2 assertions, 0 failures, 0 errors
無事、テスト通過。というワケで今日は、ここまで。