Ruby-on-rails "nil:NilClass 的未定义方法`title'" Rails 指南教程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17810348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:22:30  来源:igfitidea点击:

"undefined method `title' for nil:NilClass" Rails Guides Tutorial

ruby-on-rails

提问by szatan

I am working on RailsGuides Tutorial (creating a blog app). When I run server and open: /posts/neweverything looks fine. But, when I try to create a post I get this error:

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

NoMethodError in Posts#show

Showing /home/darek/rails_projects/blog/app/views/posts/show.html.erb where line #3 raised:

undefined method `title' for nil:NilClass

帖子中没有方法错误#show

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

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

Extracted source (around line #3):

提取的源代码(围绕第 3 行):

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

In fact post is created, and I can see title and content at /posts But when I try to use show specific post I get this error. My first clue was to change line

实际上帖子已创建,我可以在 /posts 看到标题和内容但是当我尝试使用显示特定帖子时,我收到此错误。我的第一个线索是换线

<%= @post.title %> 

to

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

Error is gone, but problem isn't solved.
When I try to show specific post I get Title, and Text forms empty. It is not what I want to see ;)

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

Ok, here is the code

好的,这是代码

Show.html.erb

显示.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

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

Rake Routes:

耙路线:

-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

Thanks for help and interest!

感谢您的帮助和兴趣!

回答by Rails Guy

you have made your methods private. Remember where you put private keyword. all the methods below that, will become private, define your methods like this. private methods in end of the controller :

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

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

Hope it will help. Thanks

希望它会有所帮助。谢谢

回答by Fred Wu

I met the same problem as you when following the tutorial. And I checked my codes again then found the reason. In the posts_controller.rbfile, you cannot put the private method in the middle of the codes, that means all the methods below (such as show, edit) will be private. Instead, put the private method at the bottom like this:

我在学习教程时遇到了和你一样的问题。我再次检查了我的代码,然后找到了原因。在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

Hope to solve your problem.

希望能解决你的问题。

回答by meligatt

In my case I was not writing this line below the class definition (maps_controller):

在我的情况下,我没有在类定义(maps_controller)下面写这一行:

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

Map is my model, after writing that line, My view worked. Be careful in not to put public code below private methods.

地图是我的模型,写完那条线后,我的观点就起作用了。注意不要将公共代码放在私有方法之下。

回答by hofffman

I have meet this problem to . I have checked all the process and code, all is as same as the tutorial. In the end, in the terminal I run:

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

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

then restart the server, reopen the localhost:3000

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

solved this problem.

解决了这个问题。

回答by David

The tutorial has a typo then, because I followed these same steps and resolved the same issue. However, I was following the tutorial

该教程有一个错字,因为我遵循了这些相同的步骤并解决了相同的问题。但是,我正在按照教程进行操作

def create
  @post = Post.new(post_params)

  @post.save
  redirect_to @post
end

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

回答by davebluedevil

For me the problem was only solved by re-executing bin/rake routes after creating show.html.erb. The instructions called to do this earlier, but re-doing it immediately solved the problem without changing anything else (since my private was the final thing in my file and I was still receiving this error).

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

回答by Amol Patil

I also ran into same error for the same tutorial, and es already rails experts have already answered the question technically. but i just wanted to say that first complete one video to understand the concept and then second time try to create with him.

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

for above issue the author gives the solution in same video, In fact he shows us this error in the video with explanation and solution(as ou might already have know now but I am answering for someone like me who will visit this question first time). Its ok to panic at this stage as we all are new but lets first understand the concepts in a video and then do the hands on.

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

回答by Cameron Belt

I know this is old but this was the first post that showed up when googling the issue so I wanted to help out others that found their way to this thread.

我知道这是旧的,但这是在谷歌搜索问题时出现的第一篇文章,所以我想帮助其他人找到这个线程。

I found yet another way to fix the problem, I changed the private keyword to public in the articles_controller.rb, saved it and went to http://localhost:3000/articles/newand created a new article.

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

When I hit save article it showed up the way it was supposed to, then I went back and changed the keyword to private and saved articles_controller.rb, and it still let me create a new article a second time but this time the method was private.

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