Ruby on Rails で "1対多" 関連を使ったサンプルを作成
d:id:fits:20070730:1185814188 で Grails を使って作成したサンプルと同様のものを Ruby on Rails で作成する。
- rails アプリケーションの作成
- モデルクラスの作成
- DB の作成
- コントローラーとビューの作成
- 実行
モデルクラスの作成
モデルクラスを生成する前に、DB のマイグレーション用のファイルが生成されるように testapp/db ディレクトリ内に migrate ディレクトリを作成しておく
>cd testapp\db >mkdir migrate
モデルクラスを script/generate を使って生成する。(testapp ディレクトリで実行)
>ruby script/generate model Author >ruby script/generate model Book
Author と Book が "1対多" の関連を持つようにするには以下のような記述を行う。
testapp/app/models/author.rb
class Author < ActiveRecord::Base has_many :books end
testapp/app/models/book.rb
class Book < ActiveRecord::Base belongs_to :author end
DB の作成
モデルクラスの生成時に作成されたマイグレーション用のファイルにテーブルのカラム設定を記述する。
testapp/db/migrate/001_create_authors.rb
class CreateAuthors < ActiveRecord::Migration def self.up create_table :authors do |t| t.column :name, :string end end ・・・ end
testapp/db/migrate/002_create_books.rb
class CreateBooks < ActiveRecord::Migration def self.up create_table :books do |t| t.column :title, :string #author_id カラムは authors テーブルへの外部キー用 t.column :author_id, :integer end end ・・・ end
テーブルの作成
rake コマンドを db:migrate を指定して実行し、DB テーブルの生成を行う(testapp ディレクトリで実行)
>rake db:migrate
コントローラーとビューの作成
script/generate に scaffold を指定してコントローラーとビューを生成する
>ruby script/generate scaffold Author >ruby script/generate scaffold Book
ここで、RoR の scaffold によって生成されたビューでは Grails にように "1対多" の関連を入力するためのドロップダウンリスト等が表示されない、そのため自分で仕組みを用意する必要がある。
Book の new や edit 時に Store をドロップダウンリストで選択できるようにするには Book の _form.rhtml を以下のように変更する。
testapp/app/views/books/_form.rhtml
<%= error_messages_for 'book' %> <!--[form:book]--> <p><label for="book_title">Title</label><br/> <%= text_field 'book', 'title' %></p> <!-- 以下を追加する --> <p>Author<br/> <%= collection_select :book, :author_id, Author.find_all, :id, :name %></p> <!--[eoform:book]-->
Author の edit 時に Book の new ページに移動するリンクを表示するには Author の edit ページと Book のコントローラーを以下のように変更する
testapp/app/views/authors/edit.rhtml
<h1>Editing author</h1> <% form_tag :action => 'update', :id => @author do %> <%= render :partial => 'form' %> <%= submit_tag 'Edit' %> <% end %> <b>Books:</b> <ul> <% @author.books.each do |b| %> <li><%= link_to h(b.title), :action => 'show', :controller => 'books', :id => b.id %></li> <% end %> </ul> <!-- Book の new ページへのリンク --> <%= link_to 'Add Book', :action => 'new', :controller => 'books', :id => @author.id %> | <%= link_to 'Show', :action => 'show', :id => @author %> | <%= link_to 'Back', :action => 'list' %>
testapp/app/controllers/books_controller.rb
class BooksController < ApplicationController ・・・ def new @book = Book.new #Author の edit ページから遷移した時に #その Author がドロップダウンリスト上で選択されているようにするための処理 if params[:id] @book.author = Author.find(params[:id]) end end ・・・ end
実行
>ruby script/server