Rails入門 日程調整アプリを作ろう6

Rails入門 日程調整アプリを作ろう5の続き。
実装 -4-(Htpasswd,routes,validation,layouts)の1-7です。

1.BASIC認証用にhtpasswdプラグインをインストール。認証をかける

1-1.コマンドプロンプトを開き、D:\workspace\adjusterに移動し、ruby script/plugin install http://wota.jp/svn/rails/plugins/branches/stable/htpasswdを入力します。

htpasswdプラグインがインストールされます。


1-2./adjuster/app/controllers/application.rbにuser、passwordを記述します。

# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base
  # Pick a unique cookie name to distinguish our session data from others'
  session :session_key => '_adjuster_session_id'
  htpasswd :user => "user", :pass => "pass"
end


1-3.http://localhost:3000/eventを表示すると、認証画面が表示されるようになります。

2.トップページをメニュー画面に変更

2-1.Eclipseのジェネレータータブを開き、プルダウンにcontroller、テキストボックスにmenu indexを入力し、実行ボタンをクリックします。


2-2./adjuster/config/routes.rbを編集します。

ActionController::Routing::Routes.draw do |map|
  # The priority is based upon order of creation: first created -> highest priority.
  
  # Sample of regular route:
  # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
  # Keep in mind you can assign values other than :controller and :action

  # Sample of named route:
  # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
  # This route can be invoked with purchase_url(:id => product.id)

  # You can have the root of your site routed by hooking up '' 
  # -- just remember to delete public/index.html.
  map.connect '', :controller => "menu"

  # Allow downloading Web Service WSDL as a file with an extension
  # instead of a file named 'wsdl'
  map.connect ':controller/service.wsdl', :action => 'wsdl'

  # Install the default route as the lowest priority.
  map.connect ':controller/:action/:id.:format'
  map.connect ':controller/:action/:id'
end


2-3./adjuster/public/index.htmlを削除します。


2-4./adjuster/app/views/menu/index.rhtmlを編集します。

<h1>Adjuster Menu</h1>
<%= link_to "User List", :controller => :user, :action => :list %><br />
<%= link_to "Event List", :controller => :event, :action => :list %>

これにより、http://localhost:3000/にアクセスした際に、作成したmenuが表示されるようになります。

3.スケジュールのnewに遷移するリンクをuser_schedules/listに追加、コントローラを変更する

3-1./adjuster/app/views/user_schedule/list.rhtmlを修正します。

<h1><%=h @event.name %> UserSchedule#list</h1>
<%= link_to 'New schedule', :controller => 'schedule', :action => 'new', :id => @event %>
<table>
  <tr>
    <th>Name</th>
    <% for schedule in @schedules %>
      <th><%=h schedule.schedule_date.strftime("%m/%d") %></th>
    <% end %>
  </tr>
  <% for user in @users %>
    <tr>
      <td><%=h user.name %></td>
      <% for user_schedule in user.user_schedules %>
        <td><%=h user_schedule.attend %></td>
      <% end %>
    </tr>
  <% end %>
</table>


3-2.スケジュール作成後、user_scheduleのlistへリダイレクトするための処理を/adjuster/app/controllers/schedule_controller.rbのcreateに設定します。

  def create
#   @schedule = Schedule.new(params[:schedule])
    @event = Event.find(params[:id])
    @schedule = @event.schedules.build(params[:schedule])
    if @schedule.save
      flash[:notice] = 'Schedule was successfully created.'
      redirect_to :controller => 'user_schedule', :action => 'list', :id => @event
    else
      render :action => 'new', :id => @event
    end
  end

4.スケジュールの並び順を変更する

4-1.以下の理由から、/adjuster/app/models/event.rbを編集します。

user_scheduleコントローラーの@event.schedulesという部分を@event.schedules.find(:all,:order =>'schedule_date')とすれば並び順は変更できます。

しかし、ここを変更の場合、他の場所でも同じようにスケジュールを取得するコードを書いた場合、その都度記述しなければならずDRYではありません。

そもそもeventからschedulesを取得する場合、普通は常に日付順に並ばせる事になるかと思います。

というわけでeventモデルのアソシエーション部分を変更します。app/models/event.rbを以下のように修正します。

class Event < ActiveRecord::Base
  has_many :schedules, :order => 'schedule_date'
end

5.validationをかける(user,event)

5-1./adjuster/app/models/user.rbを編集します。

class User < ActiveRecord::Base
  has_many :user_schedules, :dependent => :destroy
  has_many :schedules, :through => :user_schedules
  
  validates_presence_of :name, :email
  
  after_create :create_user_schedule
  def create_user_schedule
    Schedule.find(:all,
                  :conditions => ["schedule_date >= ?", Time.now.beginning_of_month]).each do |schedule|
      self.schedules << schedule
    end
  end
end


5-2./adjuster/app/models/event.rbを編集します。

class Event < ActiveRecord::Base
  has_many :schedules, :order => 'schedule_date'
  
  validates_presence_of :name, :note
end

6.menuへのリンクを共通化する

6-1./adjuster/app/views/layouts/event.rhtmlのファイル名をapplication.rhtmlに変更し、layoutsフォルダ内の他のファイルを削除します。


6-2./adjuster/app/views/layouts/application.rhtmlを編集します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title><%= controller.controller_name %> : <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

<hr />
<%= link_to_unless_current 'Menu', :controller => 'menu', :action => 'index' %>

</body>
</html>

7.スケジュールの日付の表示を修正する

7-1./adjuster/app/views/schedule/list.rhtmlの日時表示部分を編集します。*1

<h1>Adjuster Menu</h1>
<h1><%=h @event.name %> Listing schedules</h1>
<table>
  <tr>
  <% for column in Schedule.content_columns %>
    <th><%= column.human_name %></th>
  <% end %>
  </tr>
  
<% for schedule in @schedules %>
  <tr>
    <td><%=h schedule.schedule_date.strftime("%Y/%m/%d %H:%M") %></td>
    <td><%= link_to 'Show', :action => 'show', :id => schedule %></td>
    <td><%= link_to 'Edit', :action => 'edit', :id => schedule %></td>
    <td><%= link_to 'Destroy', { :action => 'destroy', :id => schedule }, :confirm => 'Are you sure?', :method => :post %></td>
  </tr>
<% end %>
</table>

<%# link_to 'Previous page', { :page => @schedule_pages.current.previous } if @schedule_pages.current.previous %>
<%# link_to 'Next page', { :page => @schedule_pages.current.next } if @schedule_pages.current.next %> 

<br />

<%= link_to 'New schedule', :action => 'new', :id => @event %>


7-2./adjuster/app/views/schedule/show.rhtmlの日時表示部分を編集します。

<% for column in Schedule.content_columns %>
<p>
  <b><%= column.human_name %>:</b> <%=h @schedule.schedule_date.strftime("%Y/%m/%d %H:%M") %>
</p>
<% end %>

<%= link_to 'Edit', :action => 'edit', :id => @schedule %> |
<%= link_to 'Back', :action => 'list', :id => @event %>


7-3./adjuster/app/views/schedule/_form.rhtmlの日時表示部分を編集します。

<%= error_messages_for 'schedule' %>

<!--[form:schedule]-->
<p><label for="schedule_schedule_date">Schedule date</label><br/>
<%= datetime_select 'schedule', 'schedule_date', :use_month_numbers => true %></p>
<!--[eoform:schedule]-->


続きはこちら

*1:日程だけでなく、時間の入力も残しました。