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

Não consigo editar um usuário: ArgumentError in Users#edit

Já concluí o curso e estou tentando fazer um projeto para praticar. Tenho seguinte erro ao tentar editar um usuário: ArgumentError in Users#edit Showing C:/Sites/wecar/app/views/users/form.html.erb where line #1 raised: First argument in form cannot contain nil or be empty as outras funções estão funcionando.segue abaixo algumas classes: classe usercontroller.rb

class UsersController < ApplicationController
    #show
    #new
    #create

    private

    def user_params
        params.require(:user).permit(:email, :nome_completo, :endereco, :rg, :cpf, :cnh, :password, :password_confirmation)
    end

    def edit
        @user = User.find(params[:id])
    end
    def update
        @user = User.find(params[:id])
        if @user.update(user_params)
            redirect_to @user, notice: 'Cadastro atualizado com sucesso!'
        else
            render action: :edit
        end
    end
end

classe views/users/edit.html.erb

<h1>Editar perfil</h1>

<%= render 'form' %>

<%= link_to "Voltar", @user %>

partial _form.html.erb

<%= form_for @user do |f| %>
<p>
    <%= f.label :nome_completo %><br />
    <%= f.text_field :nome_completo %>
</p>
<p>
    <%= f.label :endereco %><br />
    <%= f.text_field :endereco %>
</p>
<p>
    <%= f.label :email %><br />
    <%= f.text_field :email %>
</p>
<p>
    <%= f.label :cpf %><br />
    <%= f.text_field :cpf %>
</p>
<p>
    <%= f.label :rg %><br />
    <%= f.text_field :rg %>
</p>
<p>
    <%= f.label :cnh %><br />
    <%= f.text_field :cnh %>
</p>
<p>
    <%= f.label :telefone %><br />
    <%= f.text_field :telefone %>
</p>
<p>
    <%= f.label :password %><br />
    <%= f.password_field :password %>
</p>
<p>
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation %>
</p>

<p>
    <%= f.submit %>
</p>
<% end %>

classe routes.rb

Rails.application.routes.draw do
  resources :carros
  resources :users

  root 'home#index'

end

classe user.rb

class User < ApplicationRecord
    validates_presence_of :email, :nome_completo, :endereco, :cpf, :rg, :password
    validates_confirmation_of :password
    validates :email, presence: true,
                    format: { with: /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/ },
                    uniqueness: true
end
4 respostas

Me parece que ou @user ou |f| estão nulos no programa.

solução!

Só completando a do André, tem algumas actions que estão private também que não deveriam, actions sempre na parte pública.

tirei o private e funcionou. só não sei pq o recurso carros tem private e funciona:

class CarrosController < ApplicationController
  before_action :set_carro, only: [:show, :edit, :update, :destroy]

  # GET /carros
  # GET /carros.json
  def index
    @carros = Carro.all
  end

  # GET /carros/1
  # GET /carros/1.json
  def show
  end

  # GET /carros/new
  def new
    @carro = Carro.new
  end

  # GET /carros/1/edit
  def edit
  end

  # POST /carros
  # POST /carros.json
  def create
    @carro = Carro.new(carro_params)

    respond_to do |format|
      if @carro.save
        format.html { redirect_to @carro, notice: 'Carro was successfully created.' }
        format.json { render :show, status: :created, location: @carro }
      else
        format.html { render :new }
        format.json { render json: @carro.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /carros/1
  # PATCH/PUT /carros/1.json
  def update
    respond_to do |format|
      if @carro.update(carro_params)
        format.html { redirect_to @carro, notice: 'Carro was successfully updated.' }
        format.json { render :show, status: :ok, location: @carro }
      else
        format.html { render :edit }
        format.json { render json: @carro.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /carros/1
  # DELETE /carros/1.json
  def destroy
    @carro.destroy
    respond_to do |format|
      format.html { redirect_to carros_url, notice: 'Carro was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_carro
      @carro = Carro.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def carro_params
      params.require(:carro).permit(:marca, :modelo, :ano_fab, :placa, :cor, :combustivel, :GNV, :cambio, :nome_proprietario, :seguradora, :validade_seguro)
    end
end

a diferença é que carro foi criado com scaffold

Então, métodos que não são actions ficam na parte de private. Métodos que serão de apoio do controller e que podem ser utilizados em mais de uma action.

As actions padrão do Rails são métodos "especiais" é importante que estejam expostas.