Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Problemas ao tentar utilizar Objeto.errors

Estou fazendo a aula 11 no curso de ruby on rails e estou tendo um problema. Não encontrei por qual motivo me retorna o "NoMethodError in Produtos#new" quando adiciono o seguinte código no inicio de um formulario:

<% @produto.errors.full_messages.each do |message| %>
  <%= message %>
<% end %>

Se eu remover esse código funciona normalmente. Segue a codificação de meus fontes:

---- routes.rb:

Rails.application.routes.draw do
    resources :produtos, only: [:new, :create, :destroy]
    get "/produtos/busca" => "produtos#busca", as: :busca_produto
    root "produtos#index"   
end

---- produtos_controller.rb

class ProdutosController < ApplicationController

    def index 
        @produtos_por_nome = Produto.order(:nome).limit 5
        @produtos_por_preco = Produto.order(:preco).limit 2
    end

    def busca
        @nome_a_buscar = params[:nome]
        @produtos = Produto.where "nome like ?", "%#{@nome_a_buscar}%"
    end

    def create
        valores = params.require(:produto).permit :nome, :descricao, :quantidade, :preco
        @produto = Produto.new valores

        if @produto.save
            redirect_to root_url
        else
            render :new
        end
    end

    def destroy
        id = params[:id]
        Produto.destroy id
        redirect_to root_url
    end
end


---- new.html.erb

<% @produto.errors.full_messages.each do |message| %>
  <%= message %>
<% end %>

<%= form_for Produto.new do |f|%>

  <div class="form-group">
    <%= f.label :nome %>
    <%= f.text_field :nome, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= f.label :descricao %>
    <%= f.text_area :descricao, class: "form-control", rows: 4 %>
  </div>  

  <div class="form-inline">
    <div class="form-group">
      <%= f.label :quantidade %>
      <%= f.number_field :quantidade, step: 1, class: "form-control" %>
    </div>

    <div class="form-group">    
      <%= f.label :preco %>
      <%= f.number_field :preco, step: 0.1, class: "form-control" %>
    </div> 

    <%= f.submit "Criar o produto", class: "btn btn-primary" %>
  </div>  

<% end %>

e essa a mensagem que me retorna:


NoMethodError in Produtos#new

Showing /home/rian/Projetos/projetos-alura/ruby-on-rails-4_Do-zero-a-web/lojadecamisetas/app/views/produtos/new.html.erb where line #1 raised:

undefined method `errors' for nil:NilClass

Extracted source (around line #1):

<% @produto.errors.full_messages.each do |message| %>
  <%= message %>
<% end %>

<%= form_for Produto.new do |f|%>


Rails.root: /home/rian/Projetos/projetos-alura/ruby-on-rails-4_Do-zero-a-web/lojadecamisetas
Application Trace | Framework Trace | Full Trace

app/views/produtos/new.html.erb:1:in `_app_views_produtos_new_html_erb__555372304178871008_70220635152520'

Request

Parameters:

None

Toggle session dump
Toggle env dump
Response

Headers:

None

Aguardo dicas. Obrigado.

2 respostas
solução!

Rian, o problema aqui é outro: o seu produto está nulo. Olhe a linha do seu log de erro:

undefined method `errors' for nil:NilClass

Não existe um método errors no objeto nil.

Isso deve ser porque você não implementou o método new no seu controller, mas tentou usar o objeto @produto na view new.html.erb. Tente uma das duas alternativas:

#1

#new.html.erb
<% @produto.errors.full_messages.each do |message| %>
  <%= message %>
<% end unless @produto.nil? %>
#2

#ProdutoController
def new
    @produto = Produto.new
end

#new.html.erb
<%= form_for @produto do |f|%>

Isso deve resolver seu problema =) Se sim, lembre-se de marcar a resposta como solução! Se não, não hesite em pedir mais ajuda!

Abraço e bons estudos!

Marco, das duas formas funcionou corretamente. Optei pela primeira por me parecer mais apropriada para esse caso.

Muito obrigado pelo auxílio. Abraço.