Upload
masakuni-kato
View
1.388
Download
5
Embed Size (px)
Citation preview
浜松Rails3道場其の弐 Model編
Hamamatsurb#5 2011.07.13 @mackato
2011年7月13日水曜日
浜松Rails3道場の心得
習うより慣れろ
理論より実用
未知を恐れない
2011年7月13日水曜日
実際にRailsアプリを作ってみる
Wiki
全5回位で
2011年7月13日水曜日
Wikiの仕様
ページの編集と削除ができる
ページにコメントできる
ページの表示ができる
2011年7月13日水曜日
Wikiの仕様
ページの編集履歴が確認できる
ユーザー認証ができる
2011年7月13日水曜日
Wikiの仕様
ページの一覧が表示できる
2011年7月13日水曜日
Wikiの仕様ページが作成できる
2011年7月13日水曜日
今回は其の弐
スライド
Model編
実演 Q&A
参考 - Ruby on Rails Guides
Rails Database Migrations: http://bit.ly/rrH5zQActive Record Validations and Callbacks: http://bit.ly/qp5vkmActive Record Associations: http://bit.ly/n3exu9Active Record Query Interface: http://bit.ly/qaeazJ
2011年7月13日水曜日
開発環境
Ruby Version 1.9.2
Rails Version 3.0.7
.rvmrcrvm ruby-1.9.2-p180@rails-3_0_7
2011年7月13日水曜日
サンプルコードの取得GitHubから其の弐用のコードを取得
git clone git://github.com/hamamatsu-rb/rails3dojo.git
git checkout -b working 2-model_pre
開始地点のタグ作業ブランチ
2011年7月13日水曜日
テスト環境の準備FactoryGirl(テストデータ作成)、Spork(テスト高速化)の導入
Gemfileに追加group :test do gem "factory_girl_rails" gem "spork", ">= 0.9.0.rc2"end
.rspecに追加--drb
spork --bootstrap
Sporkの初期化
2011年7月13日水曜日
モデルの作成今回開発するWikiで必要なモデル
User: Wikiの編集をおこなうユーザーPage: タイトルや本文をもつWikiページComment: Pageに対するコメントHistory: Pageの更新履歴
2011年7月13日水曜日
Userモデルの作成Wikiの編集をおこなうユーザー
rails g model user name:string
rake db:migrate
2011年7月13日水曜日
UserのFactoryspec/factories.rb
Factory.define :user do ¦f¦ f.name "bob"end
spec/spec_helper.rbdef create_user(params = {}) Factory.create(:user, params)end
def build_user(params = {}) Factory.build(:user, params)end
2011年7月13日水曜日
UserのSpecspec/models/user_spec.rb
describe User do describe "#name" do it "必須" do user = build_user(:name => "") user.should_not be_valid end ... end describe "#find_or_create_by_name" do context "同じ名前のユーザーが存在する場合" do it "存在しているユーザーを取得する" do ... end end context "同じ名前のユーザーが存在しない場合" do it "新しいユーザーを作成する" do ... end end endend
クラス
メソッド
コンテキスト
スペック
2011年7月13日水曜日
Userクラスapp/models/user.rb
class User < ActiveRecord::Base validates :name, :presence => true, :length => { :maximum => 50 }, :uniqueness => trueend
SexyValidation!
validates_presence_of :namevalidates_length_of :name, :maximum => 50validates_uniqueness_of :name
Legacy Style Validation
2011年7月13日水曜日
テスト実行bundle exec rspec spec/models/user_spec.rb
User #name 必須 50文字以内 重複不可 #find_or_create_by_name 同じ名前のユーザーが存在する場合 存在しているユーザーを取得する 同じ名前のユーザーが存在しない場合 新しいユーザーを作成する
2011年7月13日水曜日
Pageモデルの作成タイトルや本文をもつWikiページ
rails g model page title:string body:text \ user_id:integer
rake db:migrate
2011年7月13日水曜日
PageのFactoryspec/factories.rb
spec/spec_helper.rbdef create_page(params = {}) Factory.create(:page, params)end
def build_page(params = {}) Factory.build(:page, params)end
Factory.sequence :page_title do ¦n¦ "Page #{n}"end
Factory.define :page do ¦f¦ f.title { Factory.next(:page_title) } f.body "Lorem ipsum dolor sit amet, ..." f.association :userend
2011年7月13日水曜日
PageのSpecspec/models/page_spec.rb(抜粋)
describe Page describe "#user" it "ページを作成したユーザー" it "必須" describe "#title" it "必須" it "255文字以内" it "重複不可" describe "#body" it "文字数は実質無制限" describe "#recent" it "最新の10件" it "作成日の降順でソート"
2011年7月13日水曜日
Pageクラスapp/models/page.rb
class Page < ActiveRecord::Base belongs_to :user
validates :user, :presence => true validates :title, :presence => true, :length => { :maximum => 255 }, :uniqueness => true scope :recent, limit(10).order("created_at DESC")end
2011年7月13日水曜日
Commentモデルの作成Pageに対するコメント
rails g model comment body:text \ page_id:integer user_id:integer
rake db:migrate
2011年7月13日水曜日
CommentのFactoryspec/factories.rb
spec/spec_helper.rbdef create_comment(params = {}) Factory.create(:comment, params)end
def build_comment(params = {}) Factory.build(:comment, params)end
Factory.define :comment do ¦f¦ f.body "Lorem ipsum dolor sit amet, ..." f.association :page f.user { ¦c¦ c.page.user }end
2011年7月13日水曜日
CommentのSpecspec/models/comment_spec.rb(抜粋)
describe Comment describe "#page" it "コメント対象のページ" it "必須"
describe "#user" it "コメントを投稿したユーザー" it "必須"
describe "#body" it "必須" it "1000文字以内"
2011年7月13日水曜日
Commentクラスapp/models/comment.rb
class Comment < ActiveRecord::Base belongs_to :page belongs_to :user validates :page, :presence => true validates :user, :presence => true validates :body, :presence => true, :length => { :maximum => 1000 }end
2011年7月13日水曜日
PageにCommentへの関連を追加
spec/models/page_spec.rb (抜粋)
app/models/page.rb
has_many :comments
describe Page ... describe "#comments" it "ページへのコメント" it "作成日の昇順でソート" it "Pageと一緒に全て削除"
2011年7月13日水曜日
Historyモデルの作成Pageの更新履歴
rails g model history \page_id:integer user_id:integer
rake db:migrate
2011年7月13日水曜日
HistoryのFactoryspec/factories.rb
spec/spec_helper.rbdef create_history(params = {}) Factory.create(:history, params)end
def build_history(params = {}) Factory.build(:history, params)end
Factory.define :history do ¦f¦ f.association :page f.user { ¦c¦ c.page.user }end
2011年7月13日水曜日
HistoryのSpecspec/models/history_spec.rb
# -*- coding: utf-8 -*-require 'spec_helper'
describe History do describe "#page" do it "履歴の対象のページ" do create_history.page.should be end end describe "#user" do it "履歴を更新したユーザー" do create_history.user.should be end endend
2011年7月13日水曜日
Historyクラスapp/models/history.rb
class History < ActiveRecord::Base belongs_to :page belongs_to :userend
2011年7月13日水曜日
PageにHistoryへの関連を追加spec/models/page_spec.rb (抜粋)
app/models/page.rb
has_many :histories
describe Page ... describe "#histories" it "ページの更新履歴" it "作成日の降順でソート" it "Pageと一緒に全て削除"
2011年7月13日水曜日
Pageの更新時に履歴を追加するspec/models/page_spec.rb (抜粋)
app/models/page.rb
describe Page ... describe "#save_by_user" it "保存の成否を返す" it "Historyを1つ追加"
def save_by_user(updater) if self.save self.histories.create(:user => updater) true else false end end
2011年7月13日水曜日
今回の開発はここまで
git checkout 2-model
作業内容をmasterにマージgit checkout mastergit merge working
作業後のコードはGitHubにありますgit clone git://github.com/hamamatsu-rb/rails3dojo.git
git branch -d working
2011年7月13日水曜日
More Rails Models
2011年7月13日水曜日
データベース構造の管理
Migrations
class CreatePages < ActiveRecord::Migration def self.up create_table :pages do ¦t¦ t.string :title t.text :body t.integer :user_id
t.timestamps end end
def self.down drop_table :pages endend
rake db:migrate [VERSION=YY..]rake db:rollback [STEP=N]rake db:migrate:redo [STEP=N]
db/migrate/20110712154821_create_pages.rbpageテーブル作成
pageテーブル削除
フィールド定義
2011年7月13日水曜日
データ検証
Validations
Validation Helpers vs SexyValidation
validates_acceptance_of :terms_of_servicevalidates_associated :friendsvalidates_confirmation_of :passwordvalidates_exclusion_of :password, :in => %w(0000)validates_format_of :login, :with => /^[a-z]+/ivalidates_inclusion_of :answer, :in => %w(Y N)validates_length_of :password, :in => 4..8validates_numericality_of :age, :only_integer => truevalidates_presence_of :login, :passwordvalidates_uniqueness_of :login
validates :terms_of_service, :acceptance => truevalidates :password, :confirmation => true, :exclusion => { :in => %w(0000) }, :length => { :in => 4..8 }, :presence => truevalidates :login, :format => { :with => /^[a-z]+/i }, :presence => true, :uniqueness => truevalidates :answer, :inclusion => { :in => %w(Y N) }
2011年7月13日水曜日
データ関連
Associations
class Order < ActiveRecord::Base belongs_to :customerend
class Supplier < ActiveRecord::Base has_one :accountend
The belongs_to Association
The has_one Association
The has_many Association
class Customer < ActiveRecord::Base has_many :ordersend
The has_many :through Association
class Physician < ActiveRecord::Base has_many :appointments has_many :patients, :through => :appointmentsend class Appointment < ActiveRecord::Base belongs_to :physician belongs_to :patientend class Patient < ActiveRecord::Base has_many :appointments has_many :physicians, :through => :appointmentsend
参考: Active Record Associations: http://bit.ly/n3exu9
2011年7月13日水曜日
データ検索
Query
Active Record Query Interface: http://bit.ly/qaeazJ
Finder methods
• where• select• group• order• limit• offset• joins• includes• lock• readonly• from• having
Retrieving a Single Object
Page.find(10)Page.where(:title => "Title 1").firstPage.last
Retrieving Multiple Objects
Page.find(1, 10)Page.all.each do ¦variable¦ page.save!end
Calculations
Page.limit(10).count #=> 11Page.limit(10).all.count #=> 10
遅延評価に注意
2011年7月13日水曜日
ActiveRecord覚えること大杉
結論
2011年7月13日水曜日
実演
2011年7月13日水曜日
Q&A
2011年7月13日水曜日
多分、ActionController
次回予告
2011年7月13日水曜日