【问题标题】:Rails: Displaying a user post form_for on a user page with nested routesRails:在具有嵌套路由的用户页面上显示用户帖子 form_for
【发布时间】:2017-01-27 08:29:21
【问题描述】:

我正在构建一个 facebook 克隆,并且我试图在每个用户的页面上都有一个文本区域,以允许他们发布帖子。我已经尝试了很多不同的方法,但都没有成功,但现在我在尝试访问用户的显示页面时遇到了这个错误:

 First argument in form cannot contain nil or be empty

使用此代码:

 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

渲染 /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)

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    您说您的表单在用户的显示页面上呈现时出现问题。如果您有这样的带有嵌套资源设置的表单:

    form_for [@user, @post]
    

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

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

    【讨论】:

    • 感谢这对我帮助很大!
    【解决方案2】:

    我假设您的 _post_form 在您转到由该帖子控制器操作处理的 posts#new 路由时已加载:

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

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

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

    ...到:

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

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

    更新

    我从您的日志中看到您将执行users#show 操作,就是这个:

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

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

    form_for [@user, @post]
    

    将此添加到您的操作中:

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

    【讨论】:

    • 感谢您的回复。我尝试实施您建议的更改,但在尝试访问用户页面时仍然遇到相同的错误
    • 请发布您的新代码,以及您要导航到的路径以及该操作的服务器日志
    • 好的,我使用服务器日志信息进行了编辑。至于路径,我认为我不需要提供一个,因为 rails 会看到 form_for 东西并根据 [@user, @post] 决定它是帖子还是补丁以及将其发布到哪里?
    • 我的意思是,要在浏览器中查看渲染表单的路径是什么?
    • 感谢您的帮助。我能够使用帖子表单部分加载用户的显示页面
    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多