Ruby on rails RubyonRails:Can';无法从注释访问用户属性
在这个应用程序中,我有一个配方模型、用户模型(Desive)和一个评论模型Ruby on rails RubyonRails:Can';无法从注释访问用户属性,ruby-on-rails,ruby,ruby-on-rails-4,devise,Ruby On Rails,Ruby,Ruby On Rails 4,Devise,在这个应用程序中,我有一个配方模型、用户模型(Desive)和一个评论模型 class User < ActiveRecord::Base has_many :recipes has_many :comments end class Recipe < ActiveRecord::Base belongs_to :user has_many :comments, :dependent => :destroy end class Comment < Act
class User < ActiveRecord::Base
has_many :recipes
has_many :comments
end
class Recipe < ActiveRecord::Base
belongs_to :user
has_many :comments, :dependent => :destroy
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :recipe
end
这是实际失败的代码
<% @recipe.comments.each do |comment| %>
<% byebug %>
<p><%= comment.content %><p>
<p><%= comment.user.first_name %></p>
<% end %>
我试着使用byebug进行调试,我能够做到“comment.user.first\u name”=>John
我不确定我这里出了什么问题,如果能得到帮助,我将不胜感激。Rails 4.2.0 btw
编辑:RecipeController#Show
class RecipesController
注释形式部分
<div class="container">
<% if user_signed_in? %>
<%= form_for([@recipe.user, @recipe, @recipe.comments.build]) do |f| %>
<%= f.label :content %><br>
<%= f.text_area :content %><br>
<br>
<%= f.submit class: "btn btn-default" %>
<% end %>
<% end %>
</div>
因为您正在迭代注释集合
@recipe.comments.each
出现您提到的错误是因为其中一条注释没有设置user
(这会导致first\u name
调用nil
,以及您提到的错误)
尝试按如下方式修改模板,以跟踪“有问题”的注释:
并替换部分中的@recipe.comments.build
:
<div class="container">
<% if user_signed_in? %>
<%= form_for([@recipe.user, @recipe, @comment]) do |f| %>
<%= f.label :content %><br>
<%= f.text_area :content %><br>
<br>
<%= f.submit class: "btn btn-default" %>
<% end %>
<% end %>
</div>
此时您不需要“链接”@recipe
和Comment
,因为它将在commentscoontroller\create
中正确处理
那是一次很好的锻炼 从技术上讲,您从不检查当前用户是否存在。 因此,当您在每个评论中迭代时,如果某个未登录的用户发布评论,则该用户将为零 要防止此错误,您可以在控制器中添加此Desive Helper:
class CommentsController < ApplicationController
before_filter :authenticate_pro_user!
class CommentsController
如果有人试图访问comments controller,它将自动重定向到登录视图。更好的处理方法是使用委派并允许nil,让我解释一下
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :recipe
delegate :first_name, to: :user, prefix: true, allow_nil: true
end
当循环到达没有用户的注释时,它将返回nil
,这将变成一个空字符串,当用户存在时,注释将转到要求用户返回其
名字
好主意!我没想到会那样做。我现在看到的是,我的评论计数器“@recipe.comments.count”显示“1条评论”。它显示注释和用户的名字,这很好。但是下面有一个匿名者。知道为什么吗?是的-在模板中尝试(只是为了调试)
,然后在控制台中,检查该ID的注释是否设置了用户
c=Comment.find(id)
p Comment.user
。这应该证明,评论中没有用户。您可以尝试在console中将用户设置为c.user=user。首先
c.save
并刷新页面,还有一件事-我假设您提供的代码只是一个摘录,这样我们就可以关注最少的代码量,但是你应该考虑的是,@丁伯尔在他的回答中提到这可能是非常糟糕的做法,但由于这是个人实践项目,所以我决定放弃我的数据库,从头开始。当我这么做的时候,我创建了一个新用户,创建了一个新配方。在配方页面上,在我添加任何评论之前,它已经显示“匿名”。在控制台中,似乎没有任何注释。
@recipe.comments.each
<% @recipe.comments.each do |comment| %>
<p><%= comment.content %><p>
<% if comment.user.nil? %>
Anonymous
<% else %>
<%= comment.user.first_name %>
<% end %>
<% end %>
class RecipesController < ApplicationController
def show
@comment = Comment.new
end
end
<div class="container">
<% if user_signed_in? %>
<%= form_for([@recipe.user, @recipe, @comment]) do |f| %>
<%= f.label :content %><br>
<%= f.text_area :content %><br>
<br>
<%= f.submit class: "btn btn-default" %>
<% end %>
<% end %>
</div>
class CommentsController < ApplicationController
before_filter :authenticate_pro_user!
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :recipe
delegate :first_name, to: :user, prefix: true, allow_nil: true
end
<% @recipe.comments.each do |comment| %>
<p><%= comment.content %><p>
<p><%= comment.user_first_name %></p> # notice it's 1 dot
<% end %>