朝練メモ

chapter 7 から。とりあえず D/B をリセットせよ、とあります。

$ bundle exec rake db:reset
db/test.sqlite3 already exists
db/test.sqlite3 already exists
db/development.sqlite3 already exists
-- create_table("users", {:force=>true})
   -> 0.8055s
-- add_index("users", ["email"], {:name=>"index_users_on_email", :unique=>true})
   -> 0.1438s
-- initialize_schema_migrations_table()
   -> 0.2889s
-- assume_migrated_upto_version(20110919112931, "db/migrate")
   -> 0.3107s
$

Tests for password validations.

ええと、spec/models/user_spec.rb を云々、とあります。まず、

  before(:each) do
    @attr = { :name => "Example User", :email => "user@example.com" }
  end

な属性増やして以下。

  before(:each) do
    @attr = { 
      :name => "Example User", 
      :email => "user@example.com",
      :password => "foobar",
      :password_confirmation => "foobar"
    }
  end

んで、後は以下を末端に追加すれば良いのか。

  describe "password validations" do

    it "should require a password" do
      User.new(@attr.merge(:password => "", :password_confirmation => "")).
        should_not be_valid
    end

    it "should require a matching password confirmation" do
      User.new(@attr.merge(:password_confirmation => "invalid")).
        should_not be_valid
    end

    it "should reject short passwords" do
      short = "a" * 5
      hash = @attr.merge(:password => short, :password_confirmation => short)
      User.new(hash).should_not be_valid
    end

    it "should reject long passwords" do
      long = "a" * 41
      hash = @attr.merge(:password => long, :password_confirmation => long)
      User.new(hash).should_not be_valid
    end
  end

うーん、rspec 良いですね。試験失敗を確認して app/models/user.rb を以下にナニ。

class User < ActiveRecord::Base
  attr_accessor :password
  attr_accessible :name, :email, :password, :password_confirmation

  email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  validates :name, :presence => true,
                    :length   => { :maximum => 50 }
  validates :email, :presence => true,
                    :format   => { :with => email_regex },
                    :uniqueness => { :case_sensitive => false }

  # Automatically create the virtual attribute 'password_confirmation'.
  validates :password, :presence     => true,
                       :confirmation => true,
                       :length       => { :within => 6..40 }
end

で、次なんですがパスワード暗号化が云々とあります。spec/models/user_spec.rb に以下を追加云々とある。

  describe "password encryption" do

    before(:each) do
      @user = User.create!(@attr)
    end

    it "should have an encrypted password attribute" do
      @user.should respond_to(:encrypted_password)
    end
  end

暗号化されてること、というナニ。で、この試験を通すために db を作りかえる模様。

$ rails generate migration add_password_to_users encrypted_password:string
      invoke  active_record
      create    db/migrate/20110920233306_add_password_to_users.rb
$

で、作成されたナニはそのままで以下を実行。

$ bundle exec rake db:migrate
==  AddPasswordToUsers: migrating =============================================
-- add_column(:users, :encrypted_password, :string)
   -> 0.0013s
==  AddPasswordToUsers: migrated (0.0015s) ====================================

$ bundle exec rake db:test:prepare
$

で、試験実行。なんですがちょっと面白いオプションがナニ。

$ bundle exec rspec spec/models/user_spec.rb \
> -e "should have an encrypted password attribute"
Run filtered including {:full_description=>/(?-mix:should\ have\ an\ encrypted\ password\ attribute)/}
.

Finished in 0.57093 seconds
1 example, 0 failures
$

限定、するのか。あと spec/models/user_spec.rb の password encryption な項に以下を追加らしい。

    it "should set the encrypted password" do
      @user.encrypted_password.should_not be_blank
    end

で、app/models/user.rb の password 云々なあたりの記述を以下にするのか。

  validates :password, :presence     => true,
                       :confirmation => true,
                       :length       => { :within => 6..40 }
  before_save :encrypt_password

  private

    def encrypt_password
      self.encrypted_password = encrypt(password)
    end

    def encrypt(string)
      string # Only a temporary implementation!
    end

どうもまだ完成には至っていない模様。そして微妙に冗長な解説が入っとるな。そして 7.2 でタイムアップしました。続きは夜に。