发布时显示Ruby on Rails错误

时间:2014-04-07 16:47:10

标签: ruby-on-rails ruby

我是RoR的初学者(8个小时),面临着一个我无法解决的问题。在其网站上的入门指南中提供的教程将通过设置帖子条目示例来完成。我收到以下错误:

NoMethodError in Posts#show
Showing /Users/khalidalghamdi/blog/app/views/posts/show.html.erb where line #3 raised:

undefined method `title' for nil:NilClass
Extracted source (around line #3):
1
2
3
4
5
6

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

  <p>

Rails.root: /Users/khalidalghamdi/blog

Application Trace | Framework Trace | Full Trace
app/views/posts/show.html.erb:3:in `_app_views_posts_show_html_erb__4427112910992919114_2164032300'
Request

Parameters:

{"id"=>"4"}

这是教程链接http://guides.rubyonrails.org/getting_started.html,我遵循5.6节。它没有在show.html.erb页面中显示已发布的详细信息。我做错了什么?

更新:控制器代码:

class PostsController < ApplicationController
    def new

    end

    def create
        @post = Post.new(post_params)

        @post.save
        redirect_to @post
    end

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


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


end

2 个答案:

答案 0 :(得分:7)

@post操作中设置实例变量PostsController#show。 目前, @post变量设置为nil ,因此您收到undefined method 'title' for nil:NilClass错误。

show移除private操作。由于您已将其设为私有,因此无法调用此操作。因此@post未设置。

例如:(由于您还没有共享代码,我举了一个例子)

class PostsController < ApplicationController
  ## ...
  def show
    @post = Post.find(params[:id])
  end
  ## ...

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

另外,更好的方法是在控制器中添加before_action,您可以在其中设置@post变量,以避免跨多个操作的冗余代码。这也使您的代码DRY

例如:

class PostsController < ApplicationController
  ## set_post would be called before show, edit, update and destroy action calls only
  before_action :set_post, only: [:show, :edit, :update, :destroy]
  ## ...

  def show
    ## No need to set @post here
  end

  ## ..
   private  

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

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

答案 1 :(得分:1)

查看您的控制器代码,您已在show方法后定义了private操作。

将它放在像这样的私有方法上面

class PostsController < ApplicationController
    def new

    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

注意:

在私有方法之后定义的任何方法也被视为private