21

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

帖子中的 NoMethodError#show

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

nil:NilClass 的未定义方法“标题”

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

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

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

<%= @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

感谢您的帮助和兴趣!

4

9 回答 9

61

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

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

希望它会有所帮助。谢谢

于 2013-07-23T12:42:21.537 回答
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

希望能解决你的问题。

于 2013-12-02T01:40:48.193 回答
1

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

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

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

于 2015-04-11T09:36:04.523 回答
1

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

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

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

解决了这个问题。

于 2017-04-07T05:11:53.657 回答
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
于 2013-10-24T19:44:30.513 回答
0

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

于 2016-04-26T20:28:27.697 回答
0

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

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

于 2016-05-15T17:05:32.990 回答
0

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

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

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

于 2016-08-08T16:30:59.740 回答
0

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

rails restart
于 2020-09-07T05:55:32.760 回答