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

Rails' Wiki - AdjusterTutorial-0004 Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

{{toc}}

'''今回分実装済みのサンプル:{{attach_anchor(adjuster.zip}}'''
!実装 -2-
!!作成手順
今回実装する内容、手順を、以下に示します。
なお、かなりのボリュームになりますので、InPlaceEditorは後で別に実装します。


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

ER図、画面、ページフロー{{fn('コントローラーとビューも分離しといたほうが良かったかも')}}で作業範囲を示した図は以下のとおりです。

{{attach_view(adjuster_vc5.png)}}

!!1.日程調整用イベントのリスト画面(Schedule/list)から日程調整画面へのリンクという流れを一旦削除
InstantRailsのメニューから”Rails Applications→Open Ruby Console Window”と選択、クリックします。

{{attach_view(ir105.gif)}}


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

{{attach_view(ir01.gif)}}

消えました。

!!2.Scheduleをscaffoldで再作成
"ruby script/generate scaffold schedule schedule"と入力して実行します。

{{attach_view(ir02.gif)}}

!!3.Schedule/listへのlinkをイベントのリスト(Event/list)に新たに作成
app/view/event/list.rhtmlを開きます。

{{attach_view(ir03.gif)}}

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

{{attach_view(ir04-2.gif)}}

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

{{attach_view(ir106.gif)}}

!!4.Event,Schedule間のassociationを記述する
app/models/からそれぞれ開きます。

{{attach_view(ir05.gif)}}

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

{{attach_view(ir06.gif)}}

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

{{attach_view(ir07.gif)}}

!!5.UserScheduleのモデルを作成する
"ruby script/generate model UserSchedule"と入力し、実行します。UserScheduleはuser_scheduleでも構いません(以下はuser_scheduleで作成しています)

{{attach_view(ir08.gif)}}

!!6.UserScheduleのカラムを定義する
db/migrateディレクトリ下に004_create_user_schedules.rbが作成されます。

{{attach_view(ir09.gif)}}

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

{{attach_view(ir10.gif)}}

!!7.Scheduleから不要な(重複した)カラムを削除する
UserScheduleに移り、不要となったuser_id,attendカラムを削除するため、migrationファイルを作成します。

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

{{attach_view(ir11.gif)}}

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

{{attach_view(ir12.gif)}}

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

{{attach_view(ir13.gif)}}

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

{{attach_view(ir14.gif)}}

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

{{attach_view(ir15-02.gif)}}
!!9.Schedule,User,UserScheduleのassociationを記述する
schedule.rbに以下のようにassociationを記述します。

{{attach_view(ir16.gif)}}

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

{{attach_view(ir17.gif)}}

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

{{attach_view(ir101.gif)}}

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

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

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

{{attach_view(ir18.gif)}}

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

{{attach_view(ir19-2.gif)}}

list.rhtmlを開きます。

{{attach_view(ir20.gif)}}

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

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

{{attach_view(ir21-2.gif)}}

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

{{attach_view(ir109.gif)}}

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

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

{{attach_view(ir108.gif)}}

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

{{attach_view(ir102-2.gif)}}

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

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

{{attach_view(ir103.gif)}}

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

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

{{attach_view(ir110.gif)}}

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

{{attach_view(ir22-2.gif)}}

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

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

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


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

{{attach_view(ir23-2.gif)}}

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

{{(attach_view(ir111.gif)}}

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

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

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

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

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

{{attach_view(ir23-2.gif)}}

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

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

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

{{attach_view(ir100-2.gif)}}

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

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

{{attach_view(ir112.gif)}}

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

{{attach_view(ir113.gif)}}

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

{{attach_view(ir24.gif)}}

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

{{attach_view(ir25.gif)}}

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

{{attach_view(ir26.gif)}}

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

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

{{attach_view(ir110.gif)}}

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

{{attach_view(ir27.gif)}}

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

{{attach_view(ir104.gif)}}

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

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

{{attach_view(ir28.gif)}}

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

{{attach_view(ir29.gif)}}

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

!!12.UserSchedule/listへのlinkをイベントのリスト(Event/list)に新たに作成
以下のように、EventからUserScheduleへのリンクを追加します。

{{attach_view(ir30-3.gif)}}

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

{{attach_view(ir107.gif)}}

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

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

{{attach_view(ir31.gif)}}

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

!!14.UserScheduleのviews/list.rhtmlに、マトリックス表表示の処理を記述。
app/views/user_schedule/list.rhtmlを以下のように記述します。

{{attach_view(ir32.gif)}}

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

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

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

{{attach_view(ir114.gif)}}

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

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

!!15.User,Schedule作成時、UserScheduleを作成する処理を記述
app/models/schedule.rbに以下のように追加します。

{{attach_view(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に以下のように追加します。

{{attach_view(ir34-2.gif)}}

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

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

{{attach_view(ir115.gif)}}

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

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

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

{{attach_view(ir116.gif)}}

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

{{attach_view(ir117.gif)}}

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

{{attach_view(ir118.gif)}}

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

{{attach_view(ir119.gif)}}

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

{{attach_view(ir123.gif)}}

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

{{attach_view(ir124.gif)}}

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

{{attach_view(ir125.gif)}}

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

{{attach_view(ir126.gif)}}

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

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

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

{{attach_view(ir127.gif)}}

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

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

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

||[[目次|AdjusterTutorial]]||[[前ページへ|AdjusterTutorial-0003]]||[[次ページへ|AdjusterTutorial-0005]]||