Harry B.
Harry B.

Reputation: 421

Rails: Displaying a user post form_for on a user page with nested routes

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

Answers (2)

DiegoSalazar
DiegoSalazar

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

Ren
Ren

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

Related Questions