私は「一人のクライアントが多くの本を持っている」という連想を持っています。
を示す書籍のインデックス ビューの代わりにclient_id => 1
、クライアントの名前を表示するように編集しました。それは機能しますが、テストは異なると言います。
クライアントとブックの例を使用してテスト データベースをシードしようとしていますが、うまく動作しないようです。
私が間違っているところがわかりますか?
「nil:NilClass」と関係があると思います。
spec/views/books/index.html.erb_spec.rb
require 'spec_helper'
describe "books/index" do
before(:each) do
assign(:clients, [
stub_model(Client,
:name => "Name",
:email => "Email Address",
)
])
assign(:books, [
stub_model(Book,
:title => "Title",
:client_id => 1
)
])
end
it "renders a list of books" do
render
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "tr>td", :text => "Title".to_s, :count => 2
assert_select "tr>td", :text => 1.to_s, :count => 2
end
end
アプリ/モデル/book.rb
class Book < ActiveRecord::Base
belongs_to :client
attr_accessible :title, :client_id
validates :title, presence: true
end
アプリ/モデル/client.rb
class Client < ActiveRecord::Base
has_many :books
attr_accessible :name, :email
before_save { |user| user.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
end
app/controllers/books_controller.rb (スニペット)
class BooksController < ApplicationController
# GET /books
# GET /books.json
def index
@books = Book.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @books }
end
end
end
アプリ/ビュー/本/index.html.erb
<h1>Listing books</h1>
<table>
<tr>
<th>Title</th>
<th>Client Name</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @books.each do |book| %>
<tr>
<td><%= book.title %></td>
<td><%= book.client.name %></td>
<td><%= link_to 'Show', book %></td>
<td><%= link_to 'Edit', edit_book_path(book) %></td>
<td><%= link_to 'Destroy', book, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Book', new_book_path %>
テスト出力
1) books/index renders a list of books
Failure/Error: render
ActionView::Template::Error:
undefined method `name' for nil:NilClass
# ./app/views/books/index.html.erb:15:in `_app_views_books_index_html_erb__##########_#####'
# ./app/views/books/index.html.erb:12:in `_app_views_books_index_html_erb__##########_#####'
# ./spec/views/books/index.html.erb_spec.rb:20:in `(root)'
ファクトリの使用
代わりに FactoryGirl を使用すると、「nil:NilClass のメソッド 'each' が未定義です」という同様のエラーが発生します。
spec/views/books/index.html.erb_spec.rb
require 'spec_helper'
describe "books/index" do
before do
FactoryGirl.create(:book)
end
it "renders a list of books" do
render
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "tr>td", :text => "Title".to_s, :count => 2
assert_select "tr>td", :text => 1.to_s, :count => 2
end
end
テスト出力
1) books/index renders a list of books
Failure/Error: render
ActionView::Template::Error:
undefined method `each' for nil:NilClass
# ./app/views/books/index.html.erb:12:in `_app_views_books_index_html_erb___##########_#####'
# ./spec/views/books/index.html.erb_spec.rb:9:in `(root)'