Nerl
Nerl

Reputation: 41

Form_for “First argument in form cannot contain nil or be empty” error

I have been trying to figure out this error for a while now and have looked at similar issues but still can't seem to figure mine out.

It is a form for adding a user's weight:

<%= form_for @weight do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_field :weight, placeholder: "Enter weight" %>
  </div>
  <div class="field">
    <%= f.hidden_field :date, :value => Time.now %>
  </div>
  <%= f.submit "Add weight", class: "btn" %>  
<% end %>

Controller:

class WeightsController < ApplicationController
before_action :correct_user, only: [:create, :update, :destroy]

def new
  @weight = Weight.new
end

def create
  @weight = current_user.weights.build(weight_params)
  if @weight.save
    flash[:success] = "Weight added!"
    redirect_to current_user
  else
    flash[:notice] = "Can not add weight"
    redirect_to current_user
  end
end

def update
  @weight = current_user.weights.order("created_at").last
  if @weight.update_attributes(weight_params)
    flash[:success] = "Weight updated"
    redirect_to current_user
  else
    flash[:notice] = "Can not update weight"
    redirect_to current_user
  end

end

def edit
  @weight = Weight.find(params[:id])
end

def show
  @weight = current_user.weights.order("created_at").last
end

private

def weight_params
  params.require(:weight).permit(:weight, :date, :user_id)
end

def correct_user
  @user = User.find(params[:id])
  redirect_to(root_url) unless current_user?(@user)
end

end

I keep getting this error:

Completed 500 Internal Server Error in 13ms (ActiveRecord: 4.4ms)
2016-03-24T02:58:16.916469+00:00 app[web.1]: 
2016-03-24T02:58:16.916496+00:00 app[web.1]:
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
2016-03-24T02:58:16.916497+00:00 app[web.1]:     1: <%= form_for @weight    do |f| %>
2016-03-24T02:58:16.916498+00:00 app[web.1]:     2:   <%= render 'shared/error_messages', object: f.object %>
2016-03-24T02:58:16.916499+00:00 app[web.1]:     3:   <div class="field">
2016-03-24T02:58:16.916499+00:00 app[web.1]:     4:     <%= f.label :weight, placeholder: "Enter weight" %>
2016-03-24T02:58:16.916500+00:00 app[web.1]:   app/views/shared/_add_weight_form.html.erb:1:in `_app_views_shared__add_weight_form_html_erb___3897731957600552245_69888716309360'

Note that I also have an edit form for weight:

<%= form_for @weight do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_field :weight, placeholder: "Add weight" %>
  </div>
  <div class="field">
    <%= f.hidden_field :date, :value => Time.now %>
  </div>
  <%= f.submit "Update Weight", class: "btn btn-primary" %>  
<% end %>

Here is my new error:

Started POST "/weights" for 98.7.88.139 at 2016-03-24 03:48:15 +0000
2016-03-24T03:48:15.107703+00:00 app[web.1]: Processing by      WeightsController#create as HTML
2016-03-24T03:48:15.107835+00:00 app[web.1]:   Parameters:       {"utf8"=>"✓",   "authenticity_token"=>"rpBU/21hOohssd2Cqbme8rZ0PbsxC3rz9cCW/kLEMJbZa4F6qFjBIRMSX9wpZSu/joOfvDgqLIitEshO6cL/kQ==", "weight"=>{"weight"=>"55",  "date"=>"2016-03-24 03:48:11 +0000"}, "commit"=>"Add weight"}
2016-03-24T03:48:15.110855+00:00 app[web.1]:   User Load (1.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", nil]]
2016-03-24T03:48:15.112601+00:00 app[web.1]: Completed 404 Not Found in 5ms (ActiveRecord: 1.3ms)
2016-03-24T03:48:15.114746+00:00 app[web.1]: 
2016-03-24T03:48:15.114753+00:00 app[web.1]: ActiveRecord::RecordNotFound (Couldn't find User with 'id'=):
2016-03-24T03:48:15.114754+00:00 app[web.1]:   app/controllers/weights_controller.rb:55:in `correct_user'

Upvotes: 1

Views: 2498

Answers (2)

Muhammad Ali
Muhammad Ali

Reputation: 2183

Here is the code below how your code should be :

new form :

<%= form_for :weight do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_field :weight, placeholder: "Enter weight" %>
    <%= hidden_field_tag :id, :value => current_user.id %>
  </div>
  <div class="field">
    <%= f.hidden_field :date, :value => Time.now %>
  </div>
  <%= f.submit "Add weight", class: "btn" %>  
<% end %>

edit form :

<%= form_for @weight do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_field :weight, placeholder: "Add weight" %>
  </div>
  <div class="field">
    <%= f.hidden_field :date, :value => Time.now %>
    <%= hidden_field_tag :id, :value => current_user.id %>
  </div>
  <%= f.submit "Update Weight", class: "btn btn-primary" %>  
<% end %>

In this case by adding id field as hidden field to your forms you will not get user.id nil error for both create & update methods and your before_action filter will work fine. OR you can simply remove update & create methods from the before_action filter list like :

before_action :correct_user, only: [:destroy]

Upvotes: 1

Ruby Racer
Ruby Racer

Reputation: 5740

You are asking your controller to verify the user upon create. But there is no params[:id] in the post route, and even if there were, it would be for weight.

So, if you want to verify user, you will either nest weight under user or use session to find current user. (supposingly you are using Devise, right)?

So, what is producing your error is the before_action filter. Either change the logic, or remove the filter for create action

Upvotes: 0

Related Questions