$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 362 to server version: 4.1.11-Debian_4sarge2-log
1 <h1>Listing expenses</h1> 2 3 <table> 4 <tr> 5 <% for column in Expense.content_columns %> 6 <th><%= column.human_name %></th> 7 <% end %> 8 <th>tags</th> 9 </tr> 10 11 <% for expense in @expenses %> 12 <tr> 13 <% for column in Expense.content_columns %> 14 <td><%=h expense.send(column.name) %></td> 15 <% end %> 16 <td> 17 <% for tag in expense.tags %> 18 <%= tag.name %> 19 <% end %> 20 </td> 21 <td><%= link_to 'Show', :action => 'show', :id => expense %></td> 22 <td><%= link_to 'Edit', :action => 'edit', :id => expense %></td> 23 <td><%= link_to 'Destroy', { :action => 'destroy', :id => expense }, :confirm => 'Are you sure?' %></td> 24 </tr> 25 <% end %> 26 </table> 27 28 <%= link_to 'Previous page', { :page => @expense_pages.current.previous } if @expense_pages.current.previous %> 29 <%= link_to 'Next page', { :page => @expense_pages.current.next } if @expense_pages.current.next %> 30 31 <br /> 32 33 <%= link_to 'New expense', :action => 'new' %>
3.コントローラー expense_controllerを更新してeditとnewビューからのリクエストを受け取るメソッドを作成します。関連を保持するためにTag.find(@params[:tag_ids] if @params[:tag_ids]のようにtag_idsを実際のTagオブジェクトに変換する必要があります。
if @params[:tag_ids]の部分はもしユーザがtagをSELECTできないときにnilオブジェクトによりエラーを回避させてます。
expenses_controller.rbの32行と37行に追加します。
1 class ExpensesController < ApplicationController 2 def index 3 list 4 render :action => 'list' 5 end 6 7 def list 8 @expense_pages, @expenses = paginate :expenses, :per_page => 10 9 end 10 11 def show 12 @expense = Expense.find(params[:id]) 13 end 14 15 def new 16 @expense = Expense.new 17 @tags = Tag.find(:all) 18 end 19 20 def create 21 @expense = Expense.new(params[:expense]) 22 if @expense.save 23 flash[:notice] = 'Expense was successfully created.' 24 redirect_to :action => 'list' 25 else 26 render :action => 'new' 27 end 28 end 29 30 def edit 31 @expense = Expense.find(params[:id]) 32 @tags = Tag.find(:all) 33 end 34 35 def update 36 @expense = Expense.find(params[:id]) 37 @expense.tags = Tag.find(@params[:tag_ids]) if @params[:tag_ids] 38 if @expense.update_attributes(params[:expense]) 39 flash[:notice] = 'Expense was successfully updated.' 40 redirect_to :action => 'show', :id => @expense 41 else 42 render :action => 'edit' 43 end 44 end 45 46 def destroy 47 Expense.find(params[:id]).destroy 48 redirect_to :action => 'list' 49 end 50 end
1 class Expense < ActiveRecord::Base 2 has_and_belongs_to_many :tags 3 4 def validate 5 if tags.blank? 6 errors.add_to_base('You must specify a tag') 7 end 8 end 9 end
結果:
複数のtagsを持つexpenseを追加します。
(図を参照)
createボタンをした後にtagsを格納したビューです
(図を参照)
チェックされ格納されたtagsを見るためにexpenseのnewコントローラで編集します
(図を参照)
expenses_tagsテーブルのエンティティを見てみましょう!
(図を参照)
謝辞: Sheldon Hearm, Ecow, Spirails, Brian NG, Brandt(敬称略)みんなアリガトー