2011/12/16 by 梅本隆史
= 配属システム作成
$ rails new haizoku_system
$ cd haizoku_system
$ nano Gemfile
以下を追記
gem 'therubyracer'
gem 'bcrypt-ruby' # ログイン機能に必要
#配属システムに以下の機能をつける
# 1, ユーザー登録
# 2, ユーザー認証
# 3, 希望研究室番号入力
# 4, 研究室登録
# 5, 集計結果一覧
#
# 1と4はユーザーに使用できないようにする.
== ユーザー登録機能作成
# user model は学籍番号とパスワードを格納する
$ rails g scaffold user number:string password_digest:string
パスワードを格納するフィールドの名称はpassword_digestとしなくてはならない点に注意
$ rake db:migrate
$ nano app/models/user.rb
以下のように編集
class User < ActiveRecord::Base
has_secure_password
# 入力されたパスワードを設定・認証するメソッドと、確認パスワードを検証するバリデータと、認証機能が追加される.
# 前に作成したpassword_digestフィールドは、裏でパスワードのハッシュ値を保存するのに使わる
validates_presence_of :password, :on => :create
# デフォルトではパスワード用の validates_presence_of 検証がないため、
# 新規ユーザが作成されたときに起動される検証機能を追加する必要がある
end
$ nano app/controllers/users_controller.rb
以下のように new, create メソッドを以下の編集
# coding : utf-8
・・・・・
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
render "new"
end
end
$ nano app/views/users/new.html.erb
以下のように編集
ユーザー作成
<%= form_for @user do |f| %>
<% if @user.errors.any?%>
Form is invalid
<% for message in @user.errors.full_messages %>
- <%= message %>
<% end %>
<% end %>
<%= f.label :学籍番号 %>
<%= f.text_field :number %>
<%= f.label :パスワード %>
<%= f.password_field :password %>
<%= f.label :パスワード確認 %>
<%= f.password_field :password_confirmation %>
<%= f.submit %>
<% end %>
== ログイン機能作成
=== sessions コントローラ作成
$ rails g controller sessions
$ nano app/controllers/sessions_controller.rb
以下のように編集
# coding : utf-8
class SessionsController < ApplicationController
skip_before_filter :check_logined
def new
end
def create
user = User.find_by_number(params[:number])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
haizoku = Haizoku.find_by_user_id(user.id)
redirect_to user_haizoku_path(user.id, haizoku.user_id), :notice => "ログインしました"
else
redirect_to login_path, :notice => "学籍番号とパスワードを確認してもう一度やり直してください"
end
end
def destroy
session[:user_id] = nil
redirect_to login_path, :notice => "ログアウトしました"
end
end
$ nano config/routes.rb
以下を追記
resources :sessions
get "login" => "sessions#new", :as => "login"
get "logout" => "sessions#destroy", :as => "logout"
$ nano app/controllers/application_controller.rb
以下のように編集
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user # ヘルパーメソッドを定義して view から使えるようにした
end
$ nano app/models/user.rb
以下を追記
attr_accessible :number, :password, :password_confirmation # 編集可能なフィールドを指定
=== ログインページの作成
$ nano app/views/sessions/new.html.erb
研究室配属システム
<%= form_tag sessions_path do %>
<%= label_tag :学籍番号 %>
<%= text_field_tag :number, params[:number] %>
<%= label_tag :パスワード %>
<%= password_field_tag :password %>
<%= submit_tag "ログイン" %>
<% end %>
==希望研究室番号入力機能作成
# /users/user_id/haizoku/:id でユーザーが自分の希望研究室の番号を入力できるようにする
# これまでの配属システムと違う点は,ユーザーを作った時点で user の haizoku も作成することが可能になった点である.
# これによりユーザーに新規作成の作業をしてもらう必要がなくなった
# ここでは以下のことをした.
# 1, user モデルと haizoku モデルの関連付け
# 2, user 作成時に haizoku も作る
# 3, haizoku ページの編集
# 4, ログインしていない場合,ログインページにとぶ処理
# 5, user 自身の haizoku 以外のページを見れなくする処理
$ rails g scaffold haizoku first:integer second:integer third:integer fourth:integer fifth:integer user_id:integer
$ rake db:migrate
=== user モデルと haizoku モデルの関連付け
$ nano app/models/user.rb
以下を追記
has_one :haizoku
$ nano app/models/haizoku.rb
以下を追記
attr_accessible :first, :second, :third, :fourth, :fifth :user_id# 編集可能なフィールドを指定
belongs_to :user
$ nano config/routes.rb
以下のように編集
HaizokuSystem::Application.routes.draw do
resources :sessions
resources :users do
resources :haizokus
end
end
$ rake routes
で haizokus が users にネストされたことを確認.
user_haizokus GET /users/:user_id/haizokus(.:format) {:action=>"index",:controller=>"haizokus"}
POST /users/:user_id/haizokus(.:format) {:action=>"create",:controller=>"haizokus"}
new_user_haizoku GET /users/:user_id/haizokus/new(.:format){:action=>"new", :controller=>"haizokus"}
edit_user_haizoku GET /users/:user_id/haizokus/:id/edit(.:format){:action=>"edit", :controller=>"haizokus"}
user_haizoku GET /users/:user_id/haizokus/:id(.:format){:action=>"show", :controller=>"haizokus"}
PUT /users/:user_id/haizokus/:id(.:format) {:action=>"update",:controller=>"haizokus"}
DELETE /users/:user_id/haizokus/:id(.:format) {:action=>"destroy",:controller=>"haizokus"}
=== user 作成時に haizoku も作る
$ nano app/controllers/users_controller.rb
create メソッドを以下のように編集
def create
@user = User.new(params[:user])
if @user.save
@haizoku = @user.create_haizoku( :user_id => @user.id)
render "new"
else
render "new"
end
end
=== haizoku に希望研究室の名前ものせるための処理
$ nano app/controllers/haizokus_controller.rb
# 以下のように show メソッドを編集
def show
@haizoku = Haizoku.find(params[:id])
# @first = Labo.find_by_number(@haizoku.first)
# @second = Labo.find_by_number(@haizoku.second)
# @third = Labo.find_by_number(@haizoku.third)
# @fourth = Labo.find_by_number(@haizoku.fourth)
# @fifth = Labo.find_by_number(@haizoku.fifth)
respond_to do |format|
format.html # show.html.erb
format.json { render json: @haizoku }
end
end
# @first などはユーザーが登録した研究室の情報を保持するために定義した.
# あとでコメントアウトをはずす.
=== haizoku ページの編集
ログイン時に /users/:user_id/haizokus/:id/ にリダイレクトして
自分の研究室希望の状況を確認する画面に飛ぶようにしている.
show.html.erb を編集する
$ nano app/views/haizokus/show.html.erb
以下のように編集
<%= @current_user.number %> さんの希望研究室の登録状況は以下のようになっています.
第 1 希望:
<%= @haizoku.first %> <% if @first %><%= @first.name %> <% end %>
第 2 希望:
<%= @haizoku.second %> <% if @second %><%= @second.name %><% end %>
第 3 希望:
<%= @haizoku.third %> <% if @third %><%= @third.name %><% end %>
第 4 希望:
<%= @haizoku.fourth %> <% if @fourth %><%= @fourth.name %><% end %>
第 5 希望:
<%= @haizoku.fifth %> <% if @fifth %><%= @fifth.name %><% end %>
$ nano app/views/haizokus/_form.html.erb
以下のように編集
<%= form_for([current_user, @haizoku]) do |f| %># <= 編集見落とし注意
<% if @haizoku.errors.any? %>
<%= pluralize(@haizoku.errors.count, "error") %> prohibited this haizoku from being saved:
<% @haizoku.errors.full_messages.each do |msg| %>
- <%= msg %>
<% end %>
<% end %>
<%= f.label :第1希望 %>
<%= f.number_field :first %>
<%= f.label :第2希望 %>
<%= f.number_field :second %>
<%= f.label :第3希望 %>
<%= f.number_field :third %>
<%= f.label :第4希望 %>
<%= f.number_field :fourth %>
<%= f.label :第5希望 %>
<%= f.number_field :fifth %>
<%= f.submit '更新',:disable_with => '処理中...'%> # ボタンの表示を"更新"にして,押したら,処理中の文字を出す
<% end %>
$ nano app/views/haizokus/edit.html.erb
以下のように編集
編集画面
<%= render 'form' %>
==haizoku のupdate メソッドの編集
以下のように編集する
# coding : utf-8
・・・・・
def update
@haizoku = Haizoku.find(params[:id])
respond_to do |format|
if @haizoku.update_attributes(params[:haizoku])
format.html { redirect_to [current_user, @haizoku], notice: '更新完了!' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @haizoku.errors, status: :unprocessable_entity }
end
end
end
=== ログインしていない場合,ログインページにとぶ処理
# コントローラーでメソッドを実行する前にログインしているか確認するフィルターをかける
# すべてのコントローラーに適用したい場合は app/controllers/application_controller.rb に記述する
# ただし,sessions コントローラーには適用させたくないので適用除外の処理をさせる
$ nano app/controllers/application_controller.rb
以下のように編集
# coding : utf-8
class ApplicationController < ActionController::Base
before_filter :check_logined
protect_from_forgery
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
# 認証状況を確認するフィルタの定義
def check_logined
if session[:user_id]
begin
@user = User.find(session[:user_id])
rescue ActiveRecord::RecordNotFound
logger.error "セッションの情報(" + session[:user_id] + ")は user_infos には存在しません。"
reset_session
end
end
unless @user
flash[:referer] = request.fullpath
redirect_to login_path, :notice => "ログインしてください"
end
end
end
$ nano app/controllers/sessions_controller.rb
以下をメソッド定義の前に追記
# ログインページでは循環しないようにログインフィルタをスキップする
skip_before_filter :check_logined
=== user 自身の haizoku 以外のページを見れなくする処理
$ nano app/controllers/haizokus_controller.rb
以下を追記
before_filter :user_checked # メソッド定義の前に記述
・・・・・
private
def user_checked
unless params[:id] .to_i == current_user.id
haizoku = Haizoku.find(current_user.id)
redirect_to user_haizoku_path(current_user, haizoku.id) , :notice => "#{request.path}にはアクセスできません"
end
end
== 集計結果を表示するページ(summary)の作成
$ rails g controller summary
$ nano app/controllers/summary_controller.rb
以下のように編集
before_filter :check_logined
def index
@haizoku = Haizoku.find(current_user) # 表示させるために必要
@name = []
@head_count =[]
@first = []
@second = []
@third = []
@fourth = []
@fifth = []
@labo = Labo.all
i=0
@labo.each do |labo|
@name[i] = labo.name
@head_count[i] = labo.head_count
@first[i] = Haizoku.count(:first, :conditions => ['first = ?',i+1])
@second[i] = Haizoku.count(:second, :conditions => ['second = ?',i+1])
@third[i] = Haizoku.count(:third, :conditions => ['third = ?',i+1])
@fourth[i] = Haizoku.count(:fourth, :conditions => ['fourth = ?',i+1])
@fifth[i] = Haizoku.count(:fifth, :conditions => ['fifth = ?',i+1])
i=i+1
end
end
$ nano app/views/summary/index.html.erb
以下のように編集
集計結果