“未定义的方法`标题'为nil:NilClass”Rails指南教程

时间:2013-07-23 12:35:03

标签: ruby-on-rails

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

  

帖子中的NoMethodError#show

     

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

     

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

提取的来源(第3行):

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

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

<%= @post.title %> 

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

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

好的,这是代码

Show.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

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

感谢您的帮助和兴趣!

9 个答案:

答案 0 :(得分:58)

您已将方法设为私有。记住你把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

希望它会有所帮助。感谢

答案 1 :(得分:6)

我在按照教程时遇到了同样的问题。我再次检查了我的代码然后找到了原因。在 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

希望能解决您的问题。

答案 2 :(得分:1)

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

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

地图是我的模型,在写完这一行后,我的观点有效。小心不要将公共代码放在私有方法下面。

答案 3 :(得分:1)

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

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

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

解决了这个问题。

答案 4 :(得分:0)

然后教程有一个错字,因为我按照这些相同的步骤解决了同样的问题。但是,我正在学习本教程

def create
  @post = Post.new(post_params)

  @post.save
  redirect_to @post
end

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

我知道这已经过时了,但这是第一篇在谷歌搜索问题时出现的帖子,所以我想帮助那些找到了解决这个问题的人。

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

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

答案 8 :(得分:0)

您需要重新启动Rails服务器。

rails restart