【问题标题】:"undefined method `title' for nil:NilClass" Rails Guides Tutorial"nil:NilClass 的未定义方法 `title'" Rails 指南教程
【发布时间】:2013-07-22 12:46:23
【问题描述】:

我正在编写 RailsGuides 教程(创建博客应用程序)。当我运行服务器并打开时:/posts/new 一切看起来都很好。但是,当我尝试创建一个帖子时,我收到了这个错误:

帖子中的NoMethodError#show

显示 /home/darek/rails_projects/blog/app/views/posts/show.html.erb 其中第 3 行 提出:

nil:NilClass 的未定义方法 `title'

提取的源代码(第 3 行附近):

1  <p>
2  <strong>Title:</strong>
3  <%= @post.title %>
4  </p>
5  <p>

实际上帖子已创建,我可以在 /posts 看到标题和内容 但是当我尝试使用 show specific post 时,我得到了这个错误。 我的第一个线索是换行

<%= @post.title %> 

<%= @post.try(:title) %>

错误消失了,但问题没有解决。
当我尝试显示特定帖子时,我得到标题,而文本表单为空。这不是我想看到的;)

好的,代码如下

显示.html.erb

<p>
  <strong>Title:</strong>
  <%= @post.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @post.text %>
</p>


<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
 <% end %>

<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %>

Posts_controller.rb

class PostsController < ApplicationController

  def new 
    @post = Post.new
  end

  def index
    @posts = Post.all
  end

  def create
  @post = Post.new(params[:post].permit(:title, :text))

  if @post.save
  redirect_to @post
  else
    render 'new'
  end
end

private
  def post_params
   params.require(:post).permit(:title, :text)
  end

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

   def edit
      @post = Post.find(params[:id])
   end

    def update
      @post = Post.find(params[:id])

      if @post.update(params[:post].permit(:title, :text))
        redirect_to @post
      else 
        render 'edit'
      end
    end

    def destroy
      @post = Post.find(params[:id])
      @post.destroy

      redirect_to posts_path
    end
end

耙子路线:

-VirtualBox:~/rails_projects/blog$ rake routes
           Prefix Verb   URI Pattern                                 Controller#Action
    post_comments GET    /posts/:post_id/comments(.:format)          comments#index
                  POST   /posts/:post_id/comments(.:format)          comments#create
 new_post_comment GET    /posts/:post_id/comments/new(.:format)      comments#new
edit_post_comment GET    /posts/:post_id/comments/:id/edit(.:format) comments#edit
     post_comment GET    /posts/:post_id/comments/:id(.:format)      comments#show
                  PATCH  /posts/:post_id/comments/:id(.:format)      comments#update
                  PUT    /posts/:post_id/comments/:id(.:format)      comments#update
                  DELETE /posts/:post_id/comments/:id(.:format)      comments#destroy
            posts GET    /posts(.:format)                            posts#index
                  POST   /posts(.:format)                            posts#create
         new_post GET    /posts/new(.:format)                        posts#new
        edit_post GET    /posts/:id/edit(.:format)                   posts#edit
             post GET    /posts/:id(.:format)                        posts#show
                  PATCH  /posts/:id(.:format)                        posts#update
                  PUT    /posts/:id(.:format)                        posts#update
                  DELETE /posts/:id(.:format)                        posts#destroy
             root GET    /                                           welcome#index
                  GET    /posts/:id(.:format)                        posts#view
                  DELETE /posts/:id(.:format)                        posts#destroy

感谢您的帮助和关注!

【问题讨论】:

  • 空格在 Ruby 中很重要!此行是否在您的源代码中正确缩进? @post = Post.new(params[:post].permit(:title, :text))? redirect_to @postparams.require(:post).permit(:title, :text) 也没有正确缩进。
  • 对不起@André Dion.. 但没关系。但是是的,如果缩进正确,它看起来很干净。
  • 你的@post 对象是否包含标题?

标签: ruby-on-rails


【解决方案1】:

你需要重启 Rails 服务器。

rails restart

【讨论】:

    【解决方案2】:

    我遇到了这个问题。我检查了所有的过程和代码,都和教程一样。 最后,在终端中我运行:

    rake db:drop,    
    rake db:create,    
    rake db:migrate
    

    然后重启服务器,重新打开localhost:3000

    解决了这个问题。

    【讨论】:

      【解决方案3】:

      我知道这很旧,但这是在谷歌上搜索问题时出现的第一个帖子,所以我想帮助其他找到这个帖子的人。

      我找到了另一种解决问题的方法,我在articles_controller.rb中将private关键字更改为public,保存并转到http://localhost:3000/articles/new 并创建了一篇新文章。

      当我点击保存文章时,它会以应有的方式显示,然后我返回并将关键字更改为私有并保存了文章_controller.rb,它仍然让我第二次创建新文章,但这次是方法是私有的。

      【讨论】:

        【解决方案4】:

        我在同一个教程中也遇到了同样的错误,并且已经有 Rails 专家在技术上回答了这个问题。 但我只想说,先完成一个视频来理解这个概念,然后第二次尝试和他一起创作。

        对于上述问题,作者在同一个视频中给出了解决方案,事实上他在视频中向我们展示了这个错误并附有解释和解决方案(你现在可能已经知道了,但我正在为某人回答像我一样会第一次访问这个问题)。在这个阶段恐慌是可以的,因为我们都是新手,但让我们先了解视频中的概念,然后动手实践。

        【讨论】:

          【解决方案5】:

          对我来说,这个问题只能通过在创建 show.html.erb 后重新执行 bin/rake 路由来解决。之前要求执行此操作的说明,但重新执行此操作立即解决了问题而无需更改任何其他内容(因为我的私人文件是我文件中的最后一件事,我仍然收到此错误)。

          【讨论】:

            【解决方案6】:

            就我而言,我没有在类定义 (maps_controller) 下方写下这一行:

                class MapsController < ApplicationController
                 before_action :set_map, only: [:show, :edit, :update,:destroy]
                 ...
                end
            

            Map 是我的模型,在写完那一行之后,我的观点就奏效了。注意不要将公共代码放在私有方法之下。

            【讨论】:

              【解决方案7】:

              我在学习教程时遇到了和你一样的问题。我再次检查了我的代码然后找到了原因。在 posts_controller.rb 文件中,不能将私有方法放在代码中间,这意味着下面的所有方法(例如 show、edit)都是私有的。相反,将私有方法放在底部,如下所示:

              class PostsController < ApplicationController
                  def new
                  end
                  def index
                      @posts = Post.all
                  end
                  def create
                      @post = Post.new(post_params)
                      @post.save
                      redirect_to @post
                  end
                  def show
                      @post = Post.find(params[:id])
                  end
                  private
                      def post_params
                          params.require(:post).permit(:title, :text)
                      end
              end
              

              希望能解决您的问题。

              【讨论】:

                【解决方案8】:

                本教程有一个错字,因为我遵循了相同的步骤并解决了相同的问题。但是,我正在学习教程

                def create
                  @post = Post.new(post_params)
                
                  @post.save
                  redirect_to @post
                end
                
                private
                  def post_params
                    params.require(:post).permit(:title, :text)
                  end
                

                【讨论】:

                  【解决方案9】:

                  您已将方法设为私有。记住你把私有关键字放在哪里。下面的所有方法都将变成私有的,像这样定义你的方法。控制器末尾的私有方法:

                  class PostsController < ApplicationController
                  
                  def new 
                    @post = Post.new
                  end
                  
                  def index
                    @posts = Post.all
                  end
                  
                  def create
                  @post = Post.new(params[:post].permit(:title, :text))
                  
                    if @post.save
                      redirect_to @post
                    else
                      render 'new'
                    end
                  end
                  
                  def show
                    @post = Post.find(params[:id])
                  end
                  
                  def edit
                    @post = Post.find(params[:id])
                  end
                  
                  def update
                    @post = Post.find(params[:id])
                  
                    if @post.update(params[:post].permit(:title, :text))
                      redirect_to @post
                    else 
                      render 'edit'
                    end
                  end
                  
                  def destroy
                    @post = Post.find(params[:id])
                    @post.destroy
                  
                    redirect_to posts_path
                  end
                  
                  
                  
                  private
                   def post_params
                    params.require(:post).permit(:title, :text)
                   end
                  
                  end
                  

                  希望它会有所帮助。谢谢

                  【讨论】:

                  • 这对 Rails 的新手非常有用。谢谢
                  • +1 表示 记住您放置私有关键字的位置。下面的所有方法都将变为私有
                  • 谢谢!教程的作者一定对这个事实感到震惊。
                  • +1!我认为私人只会将下一部分设为私有。不是它下面的一切。谢谢!
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-08-12
                  • 2017-06-06
                  • 2015-06-30
                  • 1970-01-01
                  相关资源
                  最近更新 更多