Ruby on Rails Tutorial (17)

残り二つ。Chapter 10 User microposts に突入。とりあえず branch 作成。

$ git checkout -b user-microposts

10.1 A Micropost model

とりあえず model を作りましょう、とのこと。

  • validation
  • User model との連携
10.1.1 The basic model

属性としては user_id および content とのこと。以下のソレで model を作りなさいとのこと。

$ rails generate model Micropost content:string user_id:integer
      invoke  active_record
      create    db/migrate/20130128071318_create_microposts.rb
      create    app/models/micropost.rb
      invoke    rspec
      create      spec/models/micropost_spec.rb

db/migrate 配下に migration なソレができるので add_index なナニを追加とのこと。

class CreateMicroposts < ActiveRecord::Migration
  def change
    create_table :microposts do |t|
      t.string :content
      t.integer :user_id
                        
      t.timestamps
    end
    add_index :microposts, [:user_id, :created_at]
  end
end

ユーザ別で投稿順に読みこむ必要があるので、なのか。で、minimal な test を云々とありますね。

require 'spec_helper'

describe Micropost do
  let(:user) { FactoryGirl.create(:user) }
  before do
    # This code is wrong!
    @micropost = Micropost.new(content: "Lerem ipsum", user_id: user.id)
  end

  subject { @micropost }
  it { should respond_to(:content) }
  it { should respond_to(:user_id) }
end

で、投入したら準備してテスト実行、なのか。

$ bundle exec rake db:migrate
==  CreateMicroposts: migrating ===============================================
-- create_table(:microposts)
   -> 0.5884s
-- add_index(:microposts, [:user_id, :created_at])
   -> 0.0011s
==  CreateMicroposts: migrated (0.5897s) ======================================

$ bundle exec rake db:test:prepare

で、試験実行。

$ bundle exec rspec spec/models/micropost_spec.rb

あら、試験 green 終了ですね。当り前っちゃ当り前か。や、before なブロックが云々って記述がありますね。とりあえず 10.1.3 までスルーとします。

10.1.2 Accessible attributes and the first validation

model な試験に追加がある模様。

  it {should be_valid }

  describe "when user_id is not present" do
    before { @micropost.user_id = nil }
    it {should_not be_valid }
  end

とりあえず試験実行してみて red 終了を確認。model に validation 追加とのこと。

class Micropost < ActiveRecord::Base
  attr_accessible :content, :user_id
  validates :user_id, presence: true
end

これを盛り込めば試験はパスするはず。green 終了確認。
で、いよいよ以下が誤りってのが明かになってくるのかどうか。

@micropost = Micropost.new(content: "Lorem ipsum", user_id: user.id) 

user_id は accessible ではなくなるのか。確かに変更されるとアレ。

10.1.3 User/Micropost associations

ここでようやく belongs_to とか has_many とかが出てくるんですね。で、Micropost 単体でオブジェクトを作るのではなくて

user.microposts.create

みたいなカンジで、ということなのか。つうか create! で失敗時には例外が、なんですね。なので before の中がこうなる、とのこと。

let(:user) { FactoryGirl.create(:user) }
before { @micropost = user.microposts.build(content: "Lorem ipsum") } 

なるほど。とりあえず提示されてる試験を盛り込んでおきます。試験は red です。model に has_many とか belongs_to とか書いてないので。
盛り込んだ試験は Micropost.new というメソドを呼び出して user.id を渡していますが、これが例外になること、を要求してます。この挙動は Rails 3.2.3 でないとデフォではない模様。この場合、config/application.rb で云々、ということが必要になってくるんですね。とりあえず Micropost からは :user_id は accessible ではない形に変更、なのかな。
で、試験に以下を追加なのか。

it { should respond_to(:user) }
its(:user) { should == user }

user/micropost association な確認、なのかな。あと、user_spec.rb にも microposts な属性の確認を追加とのこと。

  it { should respond_to(:authenticate) }
  it { should respond_to(:microposts) }

ここで試験実行して red 確認しておきます。
で、model への盛り込みを。
app/models/micropost.rb

class Micropost < ActiveRecord::Base
  attr_accessible :content
  belongs_to :user

  validates :user_id, presence: true
end

app/models/user.rb

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation, :admin
  has_secure_password
  has_many :microposts

試験 green 終了を確認。すばらです。若干へろへろ気味なので 10.1.4 以降は明日ってことで。あと、このチュートリアルですが、再確認必要だな、って思っています。実装というか branch なのか commit なのかを確認しつつ理解が微妙な部分をおさらいする必要ありそげ。