railstutorial.jp 7章メモ
- テーマ
- フォーム
paramsでデバッグ
<%= debug(params) if Rails.env.development? %>
- 環境
- test
- development
- production (Herokuは常にコレ)
パラメータを指定して起動
$ rails console test $ rails server --environment production $ rake db:migrate RAILS_ENV=production
Herokuのリモートコンソール
$ heroku run console
RESTfulなリソースの設定 config/routes.rb
resources :users
params[:id]に/users/1の1が入ってくる
params[:id]は文字列だが、findに渡すと数値に変換される
def show @user = User.find(params[:id]) end
factorygirlのインストール。test環境のみ。
group :test do gem 'factory_girl_rails' end
$ bundle install
spec/factories.rb
FactoryGirl.define do factory :user do name "Michael Hartl" email "michael@example.com" password "foobar" password_confirmation "foobar" end end
テストの中で、上で定義した:userが使用できるようになる
let(:user) { FactoryGirl.create(:user) }
genarateもできた
specやtest配下は自動的にロードされるのかな?
$ rails generate factory_girl:model User
create test/factories/users.rb
specやtest配下は自動的にロードされるのかな?
config/environments/test.rb
にtestの環境変数が設定できる
ここではtestの実行速度を速くしたいのでbcryptのコスト関数を下げる
ActiveModel::SecurePassword.min_cost = true
Gravatarの利用
GravatarのURL(https://secure.gravatar.com/avatar/ID)はMD5ハッシュを用いてユーザーのメールアドレスをハッシュ化している
Digest::MD5::hexdigest(email.downcase)
モデルのupdate_attributesメソッドで一部データの更新
rails c user = User.first user.update_attributes(name: "Example User", email: "example@railstutorial.org", password: "foobar", password_confirmation: "foobar")
dbの変更を全てリセットしてやり直す
rake db:reset
Capybaraの文法
visit signup_path fill_in "Name", with: "Example User" fill_in "Email", with: "user@example.com" fill_in "Password", with: "foobar" fill_in "Confirmation", with: "foobar" click_button "Create my account"
件数の取得
User.count
Rspecのメソッド - expectへのブロックを渡し - to/not_to - change
expect { click_button "Create my account" }.not_to change(User, :count)
これは次と同じ
initial = User.count click_button "Create my account" final = User.count expect(initial).to eq final
フォームの作成 form_forヘルパーメソッド
# @userはUserオブジェクト <%= form_for(@user) do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :email %> <%= f.text_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation %> <%= f.submit "Create my account", class: "btn btn-large btn-primary" %> <% end %>
rspecでdescriptionに対応するテストを実行する
ネストしたdescribeの引数文字列は連結するっぽい
$ rspec spec/requests/user_pages_spec.rb -e "signup page"
signup_pathがないというエラーが出る。。。
Failures: 1) User pages signup page Failure/Error: before { visit signup_path } NameError: undefined local variable or method `signup_path' for #<RSpec::ExampleGroups::UserPages::SignupPage:0x007ffbd0fdac18> # ./spec/requests/user_pages_spec.rb:32:in `block (3 levels) in <top (required)>' 2) User pages signup page Failure/Error: before { visit signup_path } NameError: undefined local variable or method `signup_path' for #<RSpec::ExampleGroups::UserPages::SignupPage:0x007ffbd0f94a60> # ./spec/requests/user_pages_spec.rb:32:in `block (3 levels) in <top (required)>'
spec/requests/user_pages_spec.rbに以下書いたら動いた。
require 'rails_helper' include ApplicationHelper
フォームの値はparamsとしてControllerに渡る
user[name] や user[email] -> params[:user]
strong parameters機能
このままPOSTするとActiveModel::ForbiddenAttributesError in UsersController#create となる
マスアサインメントの脆弱性
@user = User.new(params[:user])
は以前のRailsで動いた。user[admin]='1'とかを強制的に渡されると危険。
Rails4からは、paramsをそのまま渡すとエラー
Controllerでstrong parametersの利用を推奨
params.require(:user).permit(:name, :email, :password, :password_confirmation)
コントローラ間で共通のパーシャル
app/views/shared/に置く
user.errors.count user.errors.empty? user.errors.any?
include ActionView::Helpers::TextHelper pluralize(5, "error")
redirect_to でリダイレクト
# user_urlへリダイレクトすることと同様 redirect_to @user
エラーでrspecが通らない。謎。
Failure/Error: let(:user) { FactoryGirl.create(:user) } ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
test:prepareしなさいと言われたのでやってみたがないらいしい。
$ rake test:prepare rake aborted! Don't know how to build task 'test:prepare' (See full trace by running task with --trace)
db:test:prepareもRails4.1からdeprecatedらしい。
$ rake db:test:prepare WARNING: db:test:prepare is deprecated. The Rails test helper now maintains your test schema automatically, see the release notes for details.
以下でやっとテストが通った
$ rake db:create db:migrate RAILS_ENV=test $ rake spec
特殊な変数flash
flash[:success] = "Welcome to the Sample App!"
Railsでは自動的にシンボルを文字列に変換
してテンプレートに渡すようになっている
本番でSSLをつかう config/environments/production.rb
config.force_ssl = true