user4557573
user4557573

Reputation: 335

Redirect to edit page automatically if record exists

I want to create a new record if it not exist. Otherwise, redirect to edit page automatically.

In case the record exists (e.g: @sale is not nil). However, I got error message:

app/views/sales/_form.html.erb where line #1 raised:

First argument in form cannot contain nil or be empty

Please show place where I had mistake.

sales_controller.rb

  def new
    @sale = Sale.find_on_today
    if @sale.nil?
      @sale = Sale.new
    else
      redirect_to edit_sale_path(@sale)
    end
  end

  def edit
  end

  # POST /sales
  def create
    Kpi.transaction do
      @sale = Sale.new(sale_params)
      @sale.user_id = current_user.id
      respond_to do |format|
        if @sale.save
          format.html { redirect_to sales_path, notice: 'Sale was successfully created.' }
        else
          format.html { render :new }
        end
      end
    end
  end

  # PATCH/PUT /sales/1
  def update
    respond_to do |format|
      if @sale.update(sale_params)
        format.html { redirect_to sales_path, notice: 'Sale was successfully updated.' }
      else
        format.html { render :edit }
      end
    end
  end

  private
  def sale_params
    params.require(:sale).permit(:sale_money, :no_of_items)
  end

_form.html.erb

<%= form_for @sale do |f| %>
  <label for="sale_money"><%= t('.sale_money_label')%></label>
  <%= f.text_field :sale_money, class: "form-control" %>

  <label for="no_of_items"><%= t('.no_of_items_label')%></label>
  <%= f.text_field :sale_amount, class: "form-control" %>

  <%= f.submit t('.btn_submit'), class: 'btn btn-primary' %>
<% end %>

UPDATE: Based on fylooi's answer, I forget redirect is a new request, so @sale is nil. I change method new, edit and update in controller, it is working

sales_controller.rb

def new
    @sale = Sale.find_on_today
    if @sale.nil?
        @sale = Sale.new
    else
        redirect_to edit_sale_path(@sale.id)
    end
end

def edit
    @sale = Sale.find(params[:id])
end

def update
    @sale = Sale.find(params[:id])
    respond_to do |format|
      if @sale.update(kpi_params)
        format.html { redirect_to kpis_path, notice: 'Sale was successfully updated.' }
      else
        format.html { render :edit }
      end
    end
end

edit.html.erb

<%= render partial: 'form' %>

Upvotes: 0

Views: 1202

Answers (1)

fylooi
fylooi

Reputation: 3870

A redirect is a fresh request to Rails. You need to set @sale again in the edit action as it is not persisted from update.

Alternatively, you can render the edit view directly from update if the update fails. That will preserve the instance variables from update.

Upvotes: 1

Related Questions