Create  Edit  Diff  FrontPage  Index  Search  Changes  History  Source  RSS  Note  wikifarm  Login

日程調整アプリを作ろう-4-

今回分実装済みのサンプル:adjuster.zip

実装 -2-

作成手順

今回実装する内容、手順を、以下に示します。 なお、かなりのボリュームになりますので、InPlaceEditorは後で別に実装します。

  1. 不要なリンク、Schedule#indexを一旦削除
  2. ScheduleをScaffoldで再作成
  3. Schedule/listへのlinkをEvent/listに新たに作成
  4. Event,Schedule間のassociationを記述する
  5. UserScheduleのモデルを作成する
  6. UserScheduleのカラムを定義する
  7. Scheduleから不要な(重複した)カラムを削除する
  8. db:migrate
  9. Schedule,User,UserSchedule間のassociationを記述する
  10. Schedule_controller.rb、ScheduleのviewsをScheduleの親であるeventに従属するよう変更する
  11. UserScheduleのコントローラーを作成する(日程調整画面)
  12. UserSchedule/listへのlinkをEvent/listに新たに作成
  13. UserScheduleコントローラーのlistにマトリックス表示に必要な処理を記述
  14. UserScheduleのviews/list.rhtmlに、マトリックス表表示の処理を記述
  15. User,Schedule作成時、UserScheduleを作成する処理を記述

ER図、画面、ページフロー*1で作業範囲を示した図は以下のとおりです。

adjuster_vc5.png

1.日程調整用イベントのリスト画面(Schedule/list)から日程調整画面へのリンクという流れを一旦削除

InstantRailsのメニューから”Rails Applications→Open Ruby Console Window”と選択、クリックします。

ir105.gif

adjusterプロジェクトのディレクトリに移動して、”ruby script/destroy controller schedule index”と入力して実行します。

ir01.gif

消えました。

2.Scheduleをscaffoldで再作成

"ruby script/generate scaffold schedule schedule"と入力して実行します。

ir02.gif

3.Schedule/listへのlinkをイベントのリスト(Event/list)に新たに作成

app/view/event/list.rhtmlを開きます。

ir03.gif

list.rhtmlに以下の様に追加します。

ir04-2.gif

ブラウザで確認してみます。Schedule_listが作成されていますね。

ir106.gif

4.Event,Schedule間のassociationを記述する

app/models/からそれぞれ開きます。

ir05.gif

event.rbに以下の様にhas_manyを記述します。

ir06.gif

schedule.rbに以下の様にbelongs_toを記述します。

ir07.gif

5.UserScheduleのモデルを作成する

"ruby script/generate model UserSchedule"と入力し、実行します。UserScheduleはuser_scheduleでも構いません(以下はuser_scheduleで作成しています)

ir08.gif

6.UserScheduleのカラムを定義する

db/migrateディレクトリ下に004_create_user_schedules.rbが作成されます。

ir09.gif

004_create_user_schedules.rbを編集して、カラムを定義します。ここで、attendのdefaultが'-'となっているのは、InPlaceEditorの為です(後述)。

ir10.gif

7.Scheduleから不要な(重複した)カラムを削除する

UserScheduleに移り、不要となったuser_id,attendカラムを削除するため、migrationファイルを作成します。

"ruby script/migration remove_column_for_schedules"と入力、実行します。ファイル名は任意です。わかりやすい名前をつけましょう。

ir11.gif

作成された005_remove_column_for_schedules.rbを以下のように編集します。

ir12.gif

8.db:migrateしてみる

"rake db:migrate”して、UserScheduleテーブルの生成と、Scheduleカラムからの削除を行います。

ir13.gif

UserScheduleをphpMyAdminで確認してみます。無事作成されていますね。

ir14.gif

カラムを削除したScheduleも確認してみます。オッケー。削除されています。

ir15-02.gif

9.Schedule,User,UserScheduleのassociationを記述する

schedule.rbに以下のようにassociationを記述します。

ir16.gif

user.rbに以下のようにassociationを記述します。

ir17.gif

user_schedule.rbに以下のようにassociationを記述します。

ir101.gif

10.Schedule_controller.rb、ScheduleのviewsをScheduleの親であるeventに従属するよう変更する

Scheduleを変更していきます。なお、見た目は殆ど変わりませんので注意して下さい。

app/controllers/schedule_controller.rbを開きます。

ir18.gif

listの修正

eventのidがparamsで渡ってきていますので、app/controllers/schedule_controller.rbのlistを以下のように修正します。

ir19-2.gif

list.rhtmlを開きます。

ir20.gif

一番最初に<%=h @event.name %>を追加します。

また、新規作成時にどのeventのscheduleであるかを明示的に作成しますので、一番末尾、newのlink_toに、:id =>@eventを追加します。

ir21-2.gif

ブラウザで確認します。eventのlistにあるSchedule_listをクリックして表示します。一番最初にイベントの名前が表示されていますね。

ir109.gif

newに追加した部分は見た目では分からないので生成されたhtmlを確認してみます。

eventのid(ここでは1)が付加されていますね。

ir108.gif

showの修正

app/controllers/schedule_controller.rbのshowに@event = @schedule.eventを追加します。

ir102-2.gif

show.rhtmlの末尾、listへのlink_toに、:id =>@eventを追加します。

リストに戻った時にどのイベントのスケジュールなのかが特定されていないと表示されなくなった為です。

ir103.gif

これも、見た目では分からないので生成されたhtmlを確認してみます。

eventのid(ここでは1)が付加されていますね。

ir110.gif

newの修正

app/controllers/schedule_controller.rbのnewを以下のように修正します。

ir22-2.gif

追加した2行目、少しわかりづらいかもしれません。

これは要するにnewです。has_many宣言で定義されるメソッドの一つです。

親モデルに従属する子モデルをnewしているというのが明示的にわかり、私は好きです。

どのeventのscheduleなのかという情報が必要ですので、new.rhtmlの以下の2カ所に:id =>@eventを追加します。

ir23-2.gif

ブラウザで確認してみます。

ir111.gif

おっと、エラーが出てしまいました。エラーを確認すると、attendなんてメソッドはないと言ってます。場所はnew.rhtmlの7行目あたりだよと出てます。

7行目はattendのtext_fieldとなってます。

attendはさっきmigrateでカラムを削除しました(UserScheduleに移した)のでもうないですね。

migrateでattendを削除するより先にScaffoldしてしまったので、作成されたものが残ってしまいました。

というわけで、labelタグのある6行目と、この7行目を削除します。

ir23-2.gif

あれ、6行目も7行目も内容が違いますね。と、いうより、フォームの中身がごっそりありません。ではどこに?

フォームの中身は、部分テンプレートに分離されています。render :partial => 'form' となっている所です。

では、部分テンプレートを開いて削除します。app/views/scheduleにある'_form.rhtml'というファイルが部分テンプレートファイルです。部分テンプレートファイルは、_から始まるという規約になっています。

ir100-2.gif

改めてブラウザで確認します。開くのを確認して下さい。見た目では分からないので生成されたhtmlを確認してみます。

フォームのアクション部分。eventのid(ここでは1)が付加されていますね。

ir112.gif

listへのlink部分。eventのid(ここでは1)が付加されていますね。

ir113.gif

createの修正

app/controllers/schedule_controller.rbのcreateを以下のように修正します

ir24.gif

editの修正

app/controllers/schedule_controller.rbのeditに@event = @schedule.eventを追加します。

ir25.gif

edit.rhtmlの末尾、listへのlink_toに、:id =>@eventを追加します。

ir26.gif

見た目では分からないので生成されたhtmlを確認してみます。

eventのid(ここでは1)が付加されていますね。

ir110.gif

updateの修正

app/controllers/schedule_controller.rbのupdateを以下のように修正します

ir27.gif

destroyの修正

app/controllers/schedule_controller.rbのdestroyを以下のように修正します

ir104.gif

11.UserScheduleのコントローラーを作成する(日程調整画面)

"ruby script/generate controller UserSchedule list"と入力し、実行します。UserScheduleは、モデル作成時と同様に、user_scheduleでも構いません(以下はuser_scheduleで作成しています)

ir28.gif

app/controllers/user_schedule_controller.rbが作成されているのを確認します。

ir29.gif

app/views/event/list.rhtmlを開きます。

12.UserSchedule/listへのlinkをイベントのリスト(Event/list)に新たに作成

以下のように、EventからUserScheduleへのリンクを追加します。

ir30-3.gif

ブラウザで確認してみます。attendとリンクが作成されていますね。

ir107.gif

13.UserScheduleコントローラーのlistにマトリックス表示に必要なモデルを取得する処理を記述。

app/controllers/user_schedule_controller.rbのlistを以下のように記述します。

ir31.gif

5行目でマトリックス表のスケジュール日付部分表示用のモデル、6行目でユーザーとその予定のモデルを取得しています。ユーザーにuser_schedulesをjoinして、さらにscheduleで絞り込みをかけるという意図です。(が、実はミスをやらかしてます)

14.UserScheduleのviews/list.rhtmlに、マトリックス表表示の処理を記述。

app/views/user_schedule/list.rhtmlを以下のように記述します。

ir32.gif

5行目から8行目で表の日付部分を描画。

10行目から17行目でユーザ名を描画して、そのユーザの予定を描画というのを繰り返しています。

ここで一旦ブラウザで確認してみます。Schedule(1/13,14,19を追加してみました)とUser(片平,藤岡を追加してみました)を適当に追加して、event/listから、attendをクリックして開きます。

ir114.gif

ありゃ、Userが表示されません。それから予定も(attend)。

あ、UserScheduleを作成する仕掛けを実装していませんでした。仕掛けを作成しないと表示出来ないですね。

15.User,Schedule作成時、UserScheduleを作成する処理を記述

app/models/schedule.rbに以下のように追加します。

ir33-2.gif

5行目、after_createでcreate_user_scheduleというメソッドを実行と記述してます。

6行目から10行目がそのcreate_user_scheduleメソッドです。

8行目のselfはこの場合scheduleのインスタンス変数でusers<<というのは、has_manyで自動定義されるメソッドの一つです。

1.スケジュールオブジェクトを作成。after_create実行。

2.今ある全ユーザを取得してきて、それをeach。

3.一件ずつ中間テーブルUserScheduleに登録

app/models/user.rbに以下のように追加します。

ir34-2.gif

スケジュール作成時と基本的に同じで、ユーザ作成時に中間テーブルUserScheduleに登録です。違いはスケジュール取得条件に今月の頭以降の日付としているだけです。

今度はオッケーでしょうか?ScheduleとUserを追加(画面では1/20と大久保を追加)して、ブラウザでもう一回開いてみます。

ir115.gif

ありゃ、UserSchedule作成の仕掛けを実装する前に入れたデータがあるから、表ががたがたになってしまいました。

最初に入れたデータを一回消してしまいます。phpMyAdminからでもいいのですが、ここはscript/consoleを使用します。

InstantRailsの画面から”Open a Rails Console”をクリックします。

ir116.gif

コンソールが立ち上がります。

ir117.gif

Eventを削除します。文字化けは気にしないで下さい。

ir118.gif

本当に削除されたか確認。消えてますね。

ir119.gif

Userを削除。確認は省略。必要なら入力下さい。

ir123.gif

Scheduleを削除。同じく確認を省略。

ir124.gif

UserScheduleを削除。あれ?空ですね。既に削除されてるみたいです。

ir125.gif

Userを削除した時の表示をよーく見て下さい。

ir126.gif

よく見ると、UserScheduleがUser削除時に一緒に削除されていますね。これは、Userのモデルに記述した、親レコード削除時に子レコードを削除するオプション、:dependent => :destroy の機能です。

同様にSchedule側でもScheduleを削除すると、一緒に子レコードUserScheduleが削除されるのですが、今回の場合は、既に該当レコードがUserと一緒に削除されていたため、Scheduleだけが削除されたわけです。

データを全て消したので、もう一度Event,User,Scheduleを入力して日程調整画面を確認します。

ir127.gif

とりあえず日程調整画面の表示まで出来ました。

次は?

次の実装作業ではInPlaceEditorを実装します。

それから、URLを一々打つのは不便ですので、いいかげんメニュー画面を作成したいと思います。Event/listとSchedule/list、UserSchedule/list間のリンクも作成します。

目次前ページへ次ページへ

*1 コントローラーとビューも分離しといたほうが良かったかも