2015-07-22 55 views
1

我是新来的rails,最近发现我的一个演示视图在为学校项目工作时出错。错误与名称方法没有被定义,但我不确定如何解决这个问题。帮助将非常感谢!我收到的错误是:Rails - NoMethodError - 未定义的方法名称为零:NilClass

NoMethodError in Topics#show 

Showing /Users/Jason/code/bloccit/app/views/topics/show.html.erb where line #17 raised: 

undefined method `name' for nil:NilClass 

<%= link_to post.title, [@topic, post] %> 
     </h4> 
     <small> 
      submitted <%= time_ago_in_words(post.created_at) %> ago by <%= post.user.name %><br> 
      <%= post.comments.count %> Comments 
     </small> 
     </div> 

相关的文件包括..

主题/ show.html.erb

<h1><%= @topic.name %></h1> 

<% if policy(@topic).update? %> 
    <%= link_to "Edit Topic", edit_topic_path, class: 'btn btn-success' %> 
<% end %> 

<div class="row"> 
    <div class="col-md-8"> 
    <p class="lead"><%= @topic.description %></p> 
    <% @posts.each do |post| %> 
     <div class="media"> 
     <div class="media-body"> 
      <h4 class="media-heading"> 
      <%= link_to post.title, [@topic, post] %> 
      </h4> 
      <small> 
      submitted <%= time_ago_in_words(post.created_at) %> ago by <%= post.user.name %><br> 
      <%= post.comments.count %> Comments 
      </small> 
     </div> 
     </div> 
    <% end %> 
    </div> 
    <div class="col-md-4"> 
    <% if policy(Post.new).create? %> 
     <%= link_to "New Post", new_topic_post_path(@topic), class: 'btn btn-success' %> 
    <% end %> 
    </div> 
</div> 

post.rb

class Post < ActiveRecord::Base 
    has_many :comments 
    belongs_to :user 
    belongs_to :topic 

    default_scope { order('created_at DESC') } 
end 

topic.rb

class Topic < ActiveRecord::Base 
    has_many :posts 
end 

posts_controller.rb

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

    def new 
    @topic = Topic.find(params[:topic_id]) 
    @post = Post.new 
    authorize @post 
    end 

    def create 
    @topic = Topic.find(params[:topic_id]) 
    @post = Post.new(post_params) 
    @post.topic = @topic 
    authorize @post 

    if @post.save 
     flash[:notice] = "Post was saved." 
     redirect_to [@topic, @post] 
    else 
     flash[:error] = "There was an error saving the post. Please try again." 
     render :new 
    end 
    end 

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

    def update 
    @topic = Topic.find(params[:topic_id]) 
    @post = Post.find(params[:id]) 
    authorize @post 

    if @post.update_attributes(post_params) 
     flash[:notice] = "Post was updated." 
     redirect_to [@topic, @post] 
    else 
     flash[:error] = "There was an error saving the post. Please try again." 
     render :new 
    end 
    end 

    private 

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

topics_controller.rb

class TopicsController < ApplicationController 
    def index 
    @topics = Topic.all 
    authorize @topics 
    end 

    def new 
    @topic = Topic.new 
    authorize @topic 
    end 

    def show 
    @topic = Topic.find(params[:id]) 
    @posts = @topic.posts 
    authorize @topic 
    end 

    def create 
    @topic = Topic.new(topic_params) 
    authorize @topic 
    if @topic.save 
     redirect_to @topic, notice: "Topic was saved successfully." 
    else 
     flash[:error] = "Error creating topic. Please try again." 
     render :new 
    end 
    end 

    def edit 
    @topic = Topic.find(params[:id]) 
    authorize @topic 
    end 

    def update 
    @topic = Topic.find(params[:id]) 
    authorize @topic 
    if @topic.update_attributes(topic_params) 
     redirect_to @topic, notice: "Topic was updated successfully." 
    else 
     flash[:error] = "Error saving topic. Please try again." 
     render :edit 
    end 
    end 

    private 

    def topic_params 
    params.require(:topic).permit(:name, :description, :public) 
    end 
end 
+0

不,'post'是'@posts.each | post | ......块。 – max

+0

啊,你说得对。对不起,错过了。 – Amadan

+0

我看着你的UsersController,你实际上并没有把帖子和用户联系起来 - 你为什么期望post.user不是零?如果您的应用程序允许没有相关用户的帖子,您应该在尝试打印出名称之前检查是否存在post.user。 – max

回答

4

创建后,林不知道你authorize方法的实现,当你不设置user。然而,

它应该像

#assuming you have the user as `current_user` 
class PostsController < ApplicationController 
    ... 
    def create 
    @topic = Topic.find(params[:topic_id]) 
    @post = Post.new(post_params) 
    @post.user = current_user 
    @post.topic = @topic 
    ... 
    end 
    ... 
end 
+0

谢谢!这让事情发挥作用。 – jlquaccia

+0

@jlquaccia,很高兴帮助:D – sameera207

1

您的文章没有用户。你必须检查你的帖子为什么没有保存用户。为了防止这个错误,你必须检查,用户存在于后。

我宁愿用delegate,并按照law of demeter

post.rb

class Post < ActiveRecord::Base 
    has_many :comments 
    belongs_to :user 
    belongs_to :topic 

    delegate :name, :to :user, allow_nil: true, prefix: true 
    default_scope { order('created_at DESC') } 
end 

在此之后,你可以从岗位像post.user_name收到的用户名和将被转发到名字用户对象的属性。

,并在您show.html

<%= post.user.name %> 

<%= post.user_name %> 

更多的变化:请不要使用default_scope。如果你不需要order(),你总是需要unscope你的查询。