关于ruby:Rails:在具有嵌套路由的用户页面上显示用户发布form_for

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

我正在建立一个Facebook克隆,我正试图在每个用户的页面上有一个文本区域,以允许他们发布帖子。我尝试过一大堆不同的东西但没有成功,但是现在我在尝试访问用户的显示页面时遇到了这个错误:

1
 First argument in form cannot contain nil or be empty

使用此代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 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
1
2
3
4
5
6
 _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 %>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
   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
1
2
3
4
5
6
7
8
9
10
11
 class UsersController < ApplicationController

def index
    @users = User.all
end

def show
    @user = User.find(params[:id])
end

end
1
2
3
4
5
6
7
8
9
10
11
 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 %>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

呈现/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)
渲染/usr/local/lib/ruby/gems/2.3.0/gems/actionpack- 5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
呈现/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)
渲染/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
呈现/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)
在救援/布局中呈现/usr/local/lib/ruby/gems/2.3.0/gems/actionpack-`5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb(96.4ms)


您说您的表单在用户的显示页面上呈现问题。如果你有这样的形式w /嵌套资源设置如下:

1
form_for [@user, @post]

这意味着您的表单需要访问@user@post实例变量,无论何时呈现表单。在这种情况下,它位于用户控制器中的show动作中。所以你的用户控制器应该是这样的:

1
2
3
4
def show
    @user = User.find(params[:id])
    @post = @user.posts.build
end


我假设当您转到由此posts控制器操作处理的posts#new路由时,_post_form已加载:

1
2
3
4
def new
    @post = Post.new
    @user = User.find_by(id: params[:id])
end

嵌套路由(在本例中为user> post)将父资源的id放在param resource_id中,在这种情况下它将是params[:user_id]。所以,基本上,改变这一行:

1
@user = User.find_by(id: params[:id])

...至:

1
@user = User.find(params[:user_id])

这将访问参数中的正确id,如果没有找到用户(通过使用find而不是find_by)将导致异常,这将在您进入视图渲染之前提醒您任何问题。在你的情况下,@user是零,你得到你发布的form_for错误。

更新

我从你的日志中看到你要进行users#show动作,就是这个:

1
2
3
def show
    @user = User.find(params[:id])
end

正如您所看到的,您没有设置您在此处传递给表单的@post变量:

1
form_for [@user, @post]

将此添加到您的操作:

1
2
3
4
def show
    @user = User.find(params[:id])
    @post = Post.new
end