неопределенный метод «каждый» для nil: NilClass после интеграционного теста

Я разрабатываю веб-приложение с использованием Ruby on Rails, и, поскольку я все еще новичок в этом, я забыл, что должен написать тест перед кодом приложения и не хочу его переделывать. Итак, прежде чем я написал свой тест, я уже написал свои коды приложений, и все это отлично работает в браузере, но после того, как я написал свои интеграционные тесты, у меня есть целая куча ошибок ActionView::Template::Error: undefined methodeach для nil:NilClass`.

Например, я скопирую и вставлю одну ошибку, и я надеюсь, что ответы можно экстраполировать на другие мои подобные ошибки.

Ошибка:

ERROR["test_unsuccessful_edit", TransactionEditTest, 0.560911]
 test_unsuccessful_edit#TransactionEditTest (0.56s)
ActionView::Template::Error:         ActionView::Template::Error: undefined method `each' for nil:NilClass
            app/views/transactions/index.html.erb:4:in `_app_views_transactions_index_html_erb___2730839601929560472_70220029186400'
            app/controllers/transactions_controller.rb:32:in `update'
            test/integration/transaction_edit_test.rb:14:in `block in <class:TransactionEditTest>'
        app/views/transactions/index.html.erb:4:in `_app_views_transactions_index_html_erb___2730839601929560472_70220029186400'
        app/controllers/transactions_controller.rb:32:in `update'
        test/integration/transaction_edit_test.rb:14:in `block in <class:TransactionEditTest>'

  16/16: [=================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.59370s

Соответствующий интеграционный тест:

require 'test_helper'

class TransactionEditTest < ActionDispatch::IntegrationTest

  def setup
    @transaction = transactions(:test)
  end

  test "unsuccessful edit" do
    get edit_transaction_path(@transaction)
    assert_template 'transactions/edit'
    patch transaction_path(@transaction), transaction: { from:  "",
                                    to: "",
                                    amount:              "foo",
                                    description: "bar" }
    assert_template 'transactions/edit'
  end

вот мой контроллер:

  class TransactionsController < ApplicationController
  def index
    @transactions = Transaction.all
  end

  def show
    @transaction = Transaction.find(params[:id])
  end

  def new                                               
    @transaction = Transaction.new
  end

  def create                                            
    if @transaction.save
      @transactions = Transaction.all
      render 'index'
    else
      render 'new'
    end
  end

  def edit                                            
    @transaction = Transaction.find(params[:id])
  end

  def update
    @transaction = Transaction.find(params[:id])
    if @transaction.update_attributes(transaction_params)
      redirect_to(:action => 'index')                                 
    else
      render('edit')
    end
  end 


  def destroy
    Transaction.find(params[:id]).destroy
    redirect_to transactions_path
  end

  private

    def transaction_params
      params.require(:transaction).permit(:from, :to, :amount,
                                   :description)
    end
end

и мой index.html.erb

<div class="transaction_list">


  <% @transactions.each do |transaction| %>

      <li>
        <%= transaction.from %>
        <%= transaction.to %>
        <%= number_with_precision(transaction.amount, :precision => 2) %>
        <%= transaction.description %>
        <%= link_to "Edit", edit_transaction_path(transaction.id) %> |
        <%= link_to "Delete", transaction, method: :delete, data: { confirm: "Are you sure?" } %>


      </li>
  <% end %>

</div>

Я знаю, что многие люди уже спрашивали об этом в stackoverflow, но я не смог найти кого-то с таким же случаем, как у меня, я надеюсь, что кто-то не только укажет на мою ошибку, но и объяснит мне концепцию, большое спасибо!!


person ttinggggg    schedule 05.03.2015    source источник


Ответы (1)


Пытаться

  def update
    @transaction = Transaction.find(params[:id])
    @transaction.update_attributes(transaction_params)
    redirect_to(:action => 'index')
  end 

or

  def update
    @transaction = Transaction.find(params[:id])
    if @transaction.update_attributes(transaction_params)
      redirect_to(:action => 'index')                                 
    else
      @transactions = Transaction.all
      render('index')
    end
  end

в основном вам нужно установить переменную @transactions перед рендерингом

person Alper Karapınar    schedule 05.03.2015
comment
первый выдал ошибку, второй работает, большое спасибо за объяснение!!! - person ttinggggg; 05.03.2015