Reputation: 421
I'm building a facebook clone, and I'm trying to have a text area on each user's page to allow them to make posts. I've tried a whole bunch of different things with no success, but right now I am getting this error when trying to access the user's show page:
First argument in form cannot contain nil or be empty
with this code:
Rails.application.routes.draw do
resources :friends, only: [:index, :destroy]
resources :posts
resources :friend_requests
devise_for :users
devise_scope :user do
root 'devise/sessions#new'
end
resources :users, only: [:index, :show] do
resources :posts
end
get 'about', to: 'static_pages#about'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
_post_form.html.erb
<%= form_for [@user, @post] do |f| %>
<%= f.text_area :content, size: "60x12", placeholder: "What do you want to say?" %>
<%= f.submit "Post" %>
<% end %>
class PostsController < ApplicationController
def index
@posts = Post.all
end
def new
@post = Post.new
@user = User.find(params[:user_id])
end
def create
@post = current_user.posts.build(post_params)
if @post.save
flash[:success] = "Posted!"
redirect_to user_path(current_user)
else
flash[:notice] = "Post could not be submitted"
redirect_to users_path
end
end
private
def post_params
params.require(:post).permit(:content)
end
end
class UsersController < ApplicationController
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
end
users/show.html.erb
<h4>You are signed in as <%= current_user.email %>! </h4>
<% if @user == current_user %>
<%= render "notifications" %>
<%= render 'shared/post_form' %>
<% end %>
<%= params.inspect %>
<%= current_user.id %>
server log:
Processing by UsersController#show as HTML
Parameters: {"id"=>"4"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 4], ["LIMIT", 1]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 4], ["LIMIT", 1]]
Rendering users/show.html.erb within layouts/application
FriendRequest Load (0.5ms) SELECT "friend_requests".* FROM "friend_requests" WHERE "friend_requests"."friend_id" = $1 ORDER BY "friend_requests"."id" ASC LIMIT $2 [["friend_id", 4], ["LIMIT", 1000]]
Rendered users/_notifications.html.erb (2.0ms)
Rendered shared/_post_form.html.erb (3.0ms)
Rendered users/show.html.erb within layouts/application (10.2ms)
Completed 500 Internal Server Error in 23ms (ActiveRecord: 1.3ms)
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
1: <%= form_for [@user, @post] do |f| %>
2: <%= f.text_area :content, size: "60x12", placeholder: "What do you want to say?" %>
3: <%= f.submit "Post" %>
4: <% end %>
app/views/shared/_post_form.html.erb:1:in `_app_views_shared__post_form_html_erb___99030300856795657_70237723952000'
app/views/users/show.html.erb:5:in `_app_views_users_show_html_erb___3196827877852207953_70237724137160'
Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack- 5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout
Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack- 5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (6.7ms) Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack- 5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (5.0ms) Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms) Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack- `5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (96.4ms)
Upvotes: 1
Views: 1010
Reputation: 13521
I'm assuming your _post_form
is loaded when you go to your posts#new
route which is handled by this posts controller action:
def new
@post = Post.new
@user = User.find_by(id: params[:id])
end
Nested routes (in this case user > post) place the parent resource's id in the param resource_id
, in you case it would be params[:user_id]
. So, essentially, change this line:
@user = User.find_by(id: params[:id])
...to:
@user = User.find(params[:user_id])
That will access the correct id in the params and will cause an exception if no user was found (by using find
instead of find_by
), that will alert you to the any problem before you get to the view rendering. In your case the @user
was nil and you got the form_for error you posted.
Update
I see from your logs you are going to the users#show
action, which is this one:
def show
@user = User.find(params[:id])
end
as you can see, you're not setting the @post
variable which you're passing to the form here:
form_for [@user, @post]
Add this to you action:
def show
@user = User.find(params[:id])
@post = Post.new
end
Upvotes: 0
Reputation: 1374
You say that your form is having a problem rendering on the user's show page. If you have this form w/ nested resource setup like this:
form_for [@user, @post]
It means your form needs access to both the @user
and the @post
instance variable whereever the form is to be rendered. In this case, it is in the show action in your users controller. So your users controller should have something like this:
def show
@user = User.find(params[:id])
@post = @user.posts.build
end
Upvotes: 1