Ruby on Rails 3.0 日記
第14回: ユーザーとタスクの関連づけ
前々回と前回 で、Devise を使ったユーザー認証の仕組みをサンプルアプリケーションに組み込みました。
今回は、ユーザーとタスクの関連づけを行います。
ユーザーのシードデータ
データベースをリセットするたびに、手動でユーザー登録作業を行うのは面倒なので、ユーザーのシードデータを用意しましょう。
db/seeds.rb を修正します。
table_names = %w(users tasks) (省略)
新規ファイル db/seeds/development/users.rb を作成します。
%w(alpha beta gamma).each do |name|
user = User.new(
:email => "#{name}@example.com",
:password => "#{name}...",
:password_confirmation => "#{name}..."
)
user.save
user.confirm!
end
user.save でユーザーアカウントが登録されます。user.confirm! でアカウントの確認手続きが完了します。
シードデータを投入します。
% rake db:reset
モデル間の関連づけ
まず、tasks テーブルのマイグレーションファイルを修正し、整数型の user_id カラムを追加します。
class CreateTasks < ActiveRecord::Migration
def self.up
create_table :tasks do |t|
t.integer :user_id
t.string :name
(省略)
マイグレーションをやり直します。
% rake db:migrate:reset
User モデルと Task モデルの関連づけを行います。
app/models/user.rb を修正します。
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :lockable and :timeoutable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation
has_many :tasks
end
最後の行に has_many :tasks を追加しています。
次に、app/models/task.rb を修正します。
class Task < ActiveRecord::Base
belongs_to :user
scope :done, where(:done => true).order("due_date")
scope :undone, where(:done => false).order("due_date")
end
これで、User と Task が「1対多」の関係で結びつけられました。
tasks コントローラの修正
現在の index アクションは次のようになっています。
def index
@task = Task.new
@tasks = Task.undone.paginate(:page => params[:page], :per_page => 10)
end
これを次のように修正します。
def index
@task = Task.new
@tasks = current_user.tasks.undone.paginate(:page => params[:page], :per_page => 10)
end
この修正により、ログイン中のユーザー(current_user)の未完了タスクが 10 個ずつ表示されるようになります。
同様に done アクションを修正します。
def done
@task = Task.new
@tasks = current_user.tasks.done.paginate(:page => params[:page], :per_page => 10)
render :action => 'index'
end
続いて create アクションを修正します。現在のソースコードは次の通り。
def create
@task = Task.new(params[:task])
if @task.save
redirect_to :tasks
else
@tasks = Task.all(:conditions => { :done => false }, :order => "due_date")
render :action => 'index'
end
end
else の次の行は、ページネーションを導入したときに index アクションと同様に修正しておくべきでしたが、うっかりそのままになっていました。
修正後は、このようになります。
def create
@task = Task.new(params[:task])
@task.user = current_user
if @task.save
redirect_to :tasks
else
@tasks = current_user.tasks.undone.paginate(:page => params[:page], :per_page => 10)
render :action => 'index'
end
end
@task.user = current_user の行が、ユーザーとタスクの関連づけを行っている部分です。
タスクのシードデータ
タスクのシードデータ db/seeds/development/tasks.rb を修正します。
alpha = User.find_by_email('alpha@example.com')
beta = User.find_by_email('beta@example.com')
Task.create(:name => "Task 0", :due_date => Date.today, :done => true, :user => alpha)
1.upto(100) do |n|
Task.create(:name => "Task #{n}", :due_date => n.days.from_now, :done => false,
:user => n.even? ? alpha : beta)
end
偶数番号のタスクは alpha ユーザーと、奇数番号のタスクは beta ユーザーと結びつけています。
シードデータを投入します。
% rake db:reset
ブラウザで動作確認
alpha ユーザーでログインします。

すると、偶数番号のタスクだけが表示されています。

今日の日付で「電球を買う」というタスクを追加します。

「Sign out」リンクをクリックしてログアウトし、beta ユーザーでログインすると、奇数番号のタスクだけが表示されます。

(2010/05/29)
記事に関するご質問は、 hermes@oiax.jp までメールでお送りください。
ウェブサイト構築の発注先を検討されているお客様は、ご相談フォームをご利用ください。
- はじめに
- 第1回: インストール (2010/04/24)
- 第2回: 新規アプリケーションの作成 (2010/04/25)
- 第3回: コントローラとビューの生成(1) (2010/04/28)
- 第4回: コントローラとビューの生成(2) (2010/04/29)
- 第5回: データベーステーブルとモデル (2010/05/01)
- 第6回: タスクの一覧 (2010/05/02)
- 第7回: タスクの新規追加フォーム (2010/05/09)
- 第8回: タスクの新規追加 (2010/05/09)
- 第9回: タスクの完了 (2010/05/15)
- 第10回: 完了したタスクの一覧 (2010/05/16)
- 第11回: Bundler (2010/05/17)
- 第12回: ユーザー認証(1) (2010/05/18)
- 第13回: ユーザー認証(2) (2010/05/19)
- 第14回: ユーザーとタスクの関連づけ (2010/05/29)
- 第15回: Devise によるユーザー認証機能の日本語化(1) (2010/10/09)
- 第16回: Devise によるユーザー認証機能の日本語化(2) (2010/10/15)
- 第17回: Devise によるユーザー認証機能の日本語化(3) (2010/10/16)

