无法访问评论对象中的用户
Can't access user in comment object
我有以下模型,Post、评论和用户。 Comment对象属于用户,用户有很多评论。但是,当尝试呈现视图以显示评论时,无法访问用户并显示 nil:NilClass 的未定义方法“头像”。附加的头像是与用户关联的方法class。
这是评论管理员
class CommentsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_commentable
def create
@comment = @commentable.comments.new comment_params
@comment.user = current_user
@comment.save
redirect_to @commentable, notice: "Comment Posted!"
end
def index
@comments = @commentable.comments.all
@comment = @commentable.comments.new comment_params
end
private
def comment_params
params.require(:comment).permit(:body)
end
def set_commentable
@commentable = Post.find(params[:post_id])
end
end
评论模型如下:
class Comment < ApplicationRecord
belongs_to :user
belongs_to :commentable, polymorphic: true
end
这是用户模型:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
acts_as_voter
has_many :posts
has_many :comments
has_one_attached :avatar
validates :username, uniqueness: true
validates :email, uniqueness: true
end
这是我要渲染的视图。我希望评论显示在显示视图的底部 post:
<p id="notice"><%= notice %></p>
<div class="w3-container w3-card w3-white w3-round m7" style="margin:auto; display:table; min-width: 500px; max-width: 800px;"><br>
<% if @post.user.avatar.attached? %>
<%= image_tag @post.user.avatar, class: "w3-circle avatar w3-left w3-margin-right", :style => "display: inline;" %>
<% else %>
<img src="https://www.w3schools.com/w3images/avatar2.png" alt="Avatar" class="w3-left w3-circle w3-margin-right" style="width:60px">
<% end %>
<%= link_to @post do %>
<span class="w3-right w3-opacity"><%= time_ago_in_words(@post.created_at) %> ago</span>
<% end %>
<h4><%= @post.user.name %></h4> <h5>@<%= @post.user.username%></h5>
<hr class="w3-clear">
<p><%= @post.content %></p>
<% if user_signed_in? %>
<hr class="w3-clear">
<%= link_to like_post_path(@post), method: :put, class: "w3-button w3-theme-d2 w3-margin-bottom" do%>
<i class="fa fa-thumbs-up"></i>
<span class="w3-badgeM"><%= @post.get_upvotes.size %></span>
<% end %>
<button type="button" class="w3-button w3-theme-d2 w3-margin-bottom"><i class="fa fa-comment"></i></button>
<% if current_user.id == @post.user_id %>
<%= link_to edit_post_path(@post), class: "w3-button w3-theme-d1 w3-margin-bottom" do %>
<i class="fas fa-pencil-alt"></i>
<% end %>
<%= link_to @post, method: :delete, data: {confirm: "Are you sure you want to delete this post?"}, class: "w3-button w3-theme-d1 w3-margin-bottom" do %>
<i class="fas fa-trash-alt"></i>
<% end %>
<% end %>
<% else %>
<br >
<% end %>
<%= simple_form_for([@post, @post.comments.build]) do |f| %>
<div class="field">
<div class="control">
<%= f.input :body, input_html: { class: 'textarea' }, wrapper: false, label_html: { class: 'label' } %>
</div>
</div>
<%= f.button :submit, 'Leave a reply', class: "button is-primary" %>
<% end %>
<% @post.comments.each do |comment|%>
<div class="w3-container w3-card w3-round w3-margin" style="background-color: #f3f3f3; padding: 0px 5px 5px;" ><br>
<% if comment.user.avatar.attached? %>
<%= image_tag comment.user.avatar, class: "w3-circle avatar w3-left w3-margin-right", :style => "display: inline;" %>
<% else %>
<img src="https://www.w3schools.com/w3images/avatar2.png" alt="Avatar" class="w3-left w3-circle w3-margin-right" style="width:60px">
<% end %>
<% if user_signed_in? %>
<% end %>
<span class="w3-right w3-opacity"><%= time_ago_in_words(comment.created_at) %> ago</span>
<h6><%= comment.user.name %></h6> <p><strong>@<%= comment.user.username%></strong></p>
<p style="max-height: 75px; overflow:auto;"><%= comment.body %></p>
</div>
<% end %>
</div>
routes.rb 文件:
Rails.application.routes.draw do
devise_for :users
# :controllers => {registrations: 'registrations'}
resources :posts do
member do
put "like" => "posts#upvote"
put "unlike" => "posts#downvote"
end
resources :comments
end
root "posts#index"
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
但是,当我尝试渲染它时,出现以下错误:
如果我查看数据库,评论记录存在且 ID 正确:
当我在选择 post 后尝试 运行 控制台中的头像附加方法时,它似乎 return 正确并且没有抛出任何错误:
谁能帮帮我,指出我错在哪里?
谢谢:)
您的 post 似乎没有关联的用户。到目前为止,很难看到您的错误消息已缩小,但是代码的第 3 行:
<% if @post.user.avatar.attached? %>
是出现错误的地方。不是因为用户没有头像,而是因为你要找nilclass的头像。
您的两个选择是修复有问题的 @post 以便它与用户相关联(您可以从控制台点他),或者将行更改为:
<% if @post.user&.avatar.attached? %>
如果 post 的用户为 nil,这将停止执行,并且只是 return false 而不是爆炸。但是,如果您的 post 应该有一个用户附加,那么我建议修复此问题而不是更改您的逻辑以考虑 post 没有用户的情况。
首先:没有像@post
这样的实例变量,所以我会从那个开始:)
其次:我建议将所有内容包装到实现 Presenter 设计模式的对象中。我会将表示层与 business/persistence 层分开。
这实际上是一个简单的修复!我只需要将评论视图包装在 <% if !comment.user.nil? %>
内。出于某种原因,第一条评论似乎没有与之关联的用户。
我有以下模型,Post、评论和用户。 Comment对象属于用户,用户有很多评论。但是,当尝试呈现视图以显示评论时,无法访问用户并显示 nil:NilClass 的未定义方法“头像”。附加的头像是与用户关联的方法class。
这是评论管理员
class CommentsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_commentable
def create
@comment = @commentable.comments.new comment_params
@comment.user = current_user
@comment.save
redirect_to @commentable, notice: "Comment Posted!"
end
def index
@comments = @commentable.comments.all
@comment = @commentable.comments.new comment_params
end
private
def comment_params
params.require(:comment).permit(:body)
end
def set_commentable
@commentable = Post.find(params[:post_id])
end
end
评论模型如下:
class Comment < ApplicationRecord
belongs_to :user
belongs_to :commentable, polymorphic: true
end
这是用户模型:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
acts_as_voter
has_many :posts
has_many :comments
has_one_attached :avatar
validates :username, uniqueness: true
validates :email, uniqueness: true
end
这是我要渲染的视图。我希望评论显示在显示视图的底部 post:
<p id="notice"><%= notice %></p>
<div class="w3-container w3-card w3-white w3-round m7" style="margin:auto; display:table; min-width: 500px; max-width: 800px;"><br>
<% if @post.user.avatar.attached? %>
<%= image_tag @post.user.avatar, class: "w3-circle avatar w3-left w3-margin-right", :style => "display: inline;" %>
<% else %>
<img src="https://www.w3schools.com/w3images/avatar2.png" alt="Avatar" class="w3-left w3-circle w3-margin-right" style="width:60px">
<% end %>
<%= link_to @post do %>
<span class="w3-right w3-opacity"><%= time_ago_in_words(@post.created_at) %> ago</span>
<% end %>
<h4><%= @post.user.name %></h4> <h5>@<%= @post.user.username%></h5>
<hr class="w3-clear">
<p><%= @post.content %></p>
<% if user_signed_in? %>
<hr class="w3-clear">
<%= link_to like_post_path(@post), method: :put, class: "w3-button w3-theme-d2 w3-margin-bottom" do%>
<i class="fa fa-thumbs-up"></i>
<span class="w3-badgeM"><%= @post.get_upvotes.size %></span>
<% end %>
<button type="button" class="w3-button w3-theme-d2 w3-margin-bottom"><i class="fa fa-comment"></i></button>
<% if current_user.id == @post.user_id %>
<%= link_to edit_post_path(@post), class: "w3-button w3-theme-d1 w3-margin-bottom" do %>
<i class="fas fa-pencil-alt"></i>
<% end %>
<%= link_to @post, method: :delete, data: {confirm: "Are you sure you want to delete this post?"}, class: "w3-button w3-theme-d1 w3-margin-bottom" do %>
<i class="fas fa-trash-alt"></i>
<% end %>
<% end %>
<% else %>
<br >
<% end %>
<%= simple_form_for([@post, @post.comments.build]) do |f| %>
<div class="field">
<div class="control">
<%= f.input :body, input_html: { class: 'textarea' }, wrapper: false, label_html: { class: 'label' } %>
</div>
</div>
<%= f.button :submit, 'Leave a reply', class: "button is-primary" %>
<% end %>
<% @post.comments.each do |comment|%>
<div class="w3-container w3-card w3-round w3-margin" style="background-color: #f3f3f3; padding: 0px 5px 5px;" ><br>
<% if comment.user.avatar.attached? %>
<%= image_tag comment.user.avatar, class: "w3-circle avatar w3-left w3-margin-right", :style => "display: inline;" %>
<% else %>
<img src="https://www.w3schools.com/w3images/avatar2.png" alt="Avatar" class="w3-left w3-circle w3-margin-right" style="width:60px">
<% end %>
<% if user_signed_in? %>
<% end %>
<span class="w3-right w3-opacity"><%= time_ago_in_words(comment.created_at) %> ago</span>
<h6><%= comment.user.name %></h6> <p><strong>@<%= comment.user.username%></strong></p>
<p style="max-height: 75px; overflow:auto;"><%= comment.body %></p>
</div>
<% end %>
</div>
routes.rb 文件:
Rails.application.routes.draw do
devise_for :users
# :controllers => {registrations: 'registrations'}
resources :posts do
member do
put "like" => "posts#upvote"
put "unlike" => "posts#downvote"
end
resources :comments
end
root "posts#index"
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
但是,当我尝试渲染它时,出现以下错误:
如果我查看数据库,评论记录存在且 ID 正确:
当我在选择 post 后尝试 运行 控制台中的头像附加方法时,它似乎 return 正确并且没有抛出任何错误:
谁能帮帮我,指出我错在哪里? 谢谢:)
您的 post 似乎没有关联的用户。到目前为止,很难看到您的错误消息已缩小,但是代码的第 3 行:
<% if @post.user.avatar.attached? %>
是出现错误的地方。不是因为用户没有头像,而是因为你要找nilclass的头像。
您的两个选择是修复有问题的 @post 以便它与用户相关联(您可以从控制台点他),或者将行更改为:
<% if @post.user&.avatar.attached? %>
如果 post 的用户为 nil,这将停止执行,并且只是 return false 而不是爆炸。但是,如果您的 post 应该有一个用户附加,那么我建议修复此问题而不是更改您的逻辑以考虑 post 没有用户的情况。
首先:没有像@post
这样的实例变量,所以我会从那个开始:)
其次:我建议将所有内容包装到实现 Presenter 设计模式的对象中。我会将表示层与 business/persistence 层分开。
这实际上是一个简单的修复!我只需要将评论视图包装在 <% if !comment.user.nil? %>
内。出于某种原因,第一条评论似乎没有与之关联的用户。