JohnTitor JohnTitor - 6 months ago 25
Ruby Question

Using another model in view causing test errors

app/views/products/index.html.erb:

<p id="notice"><%= notice %></p>

<%= render 'search' %>

<h1>Listing Products</h1>

<br>

<%= will_paginate @products %>
<% if @products.present? %>

<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Image</th>
<th>Price</th>
<th>Category</th>
<th colspan="3"></th>
</tr>
</thead>

<tbody>
<% @products.each do |product| %>
<tr>
<td><%= product.title %></td>
<td><%= product.description %></td>
<td><%= image_tag product.photo.url(:small) %></td>
<td><%= number_to_currency(product.price, :unit => '$') %></td>
<td><%= link_to Category.find(product.category_id).name, category_path(product.category_id) %></td>
<td><%= link_to 'Show', product %></td>
<% if current_user.try(:admin?) %>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
<td><a href="/cart/<%= product.id %>">Add To Cart</a></td>
</tr>
<% end %>
</tbody>
</table>

<% else %>
<% if params[:search].present? %>
<p>There are no products containing the term(s) <b><%= params[:search] %></b>.</p>
<% else %>
<p>There are no any products found in database.</p>
<% end %>
<% end %>

<br>
<% if current_user.try(:admin?) %>
<%= link_to 'New Product', new_product_path %>
<% end %>


app/views/products/show.html.erb:

<p id="notice"><%= notice %></p>

<p>
<strong>Title:</strong>
<%= @product.title %>
</p>

<p>
<strong>Description:</strong>
<%= @product.description %>
</p>

<p>
<strong>Image:</strong>
<%= image_tag @product.photo.url(:original) %>
</p>

<p>
<strong>Price:</strong>
<%= @product.price %>
</p>

<p>
<strong>Category:</strong>
<%= @product.category.name %>
</p>

<%= social_share_button_tag(@product.title, :url => request.original_url, :image => root_url + @product.photo.url(:small), desc: @product.description, via: "SCOR") %>

<% if current_user.try(:admin?) %>
<%= link_to 'Edit', edit_product_path(@product) %> |
<% end %>
<%= link_to 'Back', products_path %>


My tests in test/controllers/product_controller_test.rb

test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:products)
end

test "should show product" do
get :show, id: @product
assert_response :success
end


Causing these errors:

1) Error:
ProductsControllerTest#test_should_get_index:
ActionView::Template::Error: Couldn't find Category with 'id'=1
app/views/products/index.html.erb:31:in `block in _app_views_products_index_html_erb___969781135508440478_70267650596940'
app/views/products/index.html.erb:25:in `_app_views_products_index_html_erb___969781135508440478_70267650596940'
test/controllers/products_controller_test.rb:15:in `block in <class:ProductsControllerTest>'


2) Error:
ProductsControllerTest#test_should_show_product:
ActionView::Template::Error: undefined method `name' for nil:NilClass
app/views/products/show.html.erb:25:in `_app_views_products_show_html_erb___1500506684449289207_70267650787820'
test/controllers/products_controller_test.rb:36:in `block in <class:ProductsControllerTest>'


I'm running my tests with
rake test:functionals
. The other tests for create, update and destroy is working but I'm getting errors from the tests for index and show action.

As you can see I'm using Categories model in Products view and obviously it's causing these errors. So how can I solve this issue?

I mean these lines in views are problematic:

<td><%= link_to Category.find(product.category_id).name, category_path(product.category_id) %></td>


and

<%= @product.category.name %>


If you want to look to the whole project: https://github.com/mertyildiran/SCOR

Answer

In your products fixtures, you define a product with a category_id = 1

When you run your tests it cannot find a Category with an id = 1

in test/fixtures/products.yml :

replace :

category_id: 1

by

category: one

why 'one' ? because in test/fixtures/categories.yml, you define a category labeled one :

one:
  name: New T-Shirts
  desc: Example category description

You should not reference id in fixtures, use associations instead.

A nice post about that subject : http://blog.bigbinary.com/2014/09/21/tricks-and-tips-for-using-fixtures-in-rails.html

Also, you should replace :

link_to Category.find(product.category_id).name, category_path(product.category_id)

by

link_to product.category.name, category_path(product.category)