我有3个模特
pre_writing.rb
class PreWriting < ApplicationRecord
belongs_to :students, optional: true
belongs_to :classrooms, optional: true
belongs_to :options, optional: true
end
student.rb
has_many :pre_writings
classroom.rb
has_many :pre_writings
has_many :classroom_students
在classroom / show.html.erb
<% @classroom.students.each do |element| %>
<% if @classroom.user_id == current_user.id %>
<%= element.pre_writings.ids.first.updated_at %>
<% end %>
<% end %>
我收到错误
undefined method `updated_at' for nil:NilClass
如果我尝试
<%= element.pre_writings.ids.first %>
我可以获得id
并在控制台中尝试
classroom.students.find(86).pre_writings.first.updated_at
我得到了值
Student Load (0.1ms) SELECT "students".* FROM "students" INNER JOIN "classroom_students" ON "students"."id" = "classroom_students"."student_id" WHERE "classroom_students"."classroom_id" = ? AND "students"."id" = ? LIMIT ? [["classroom_id", 7], ["id", 86], ["LIMIT", 1]]
PreWriting Load (0.2ms) SELECT "pre_writings".* FROM "pre_writings" WHERE "pre_writings"."student_id" = ? ORDER BY "pre_writings"."id" ASC LIMIT ? [["student_id", 86], ["LIMIT", 1]]
=> Tue, 19 Dec 2017 23:50:52 UTC +00:00
有人可以告诉我为什么我会收到未定义的方法错误
答案 0 :(得分:2)
您的代码中的问题是,使用.ids您将返回一个pre_writing id数组,然后使用.first
您选择第一个ID并尝试访问未定义的方法(updated_at)对于那个id类型(可能是整数)。
此外,在执行查询时,建议检查是否实际返回了某些内容或结果集是否为空。 .first
ActiveRecord方法就是这种情况,通过检查查询是否返回了结果,您正在避免使用nil:NilClass access errors
。
您可能想要做的是:
<% @classroom.students.each do |element| %>
<% if @classroom.user_id == current_user.id %>
<% @first = element.pre_writings.first %>
<% if @first.present? %>
<%= @first.updated_at %>
<% else %>
- no record
<% end %>
<% end %>
<% end %>
修改强>
你也可以压缩
<% @first = element.pre_writings.first %>
<% if @first.present? %>
<%= @first.updated_at %>
<% else %>
- no record
<% end %>
到
<%= element.pre_writings.first&.updated_at || "no record" %>
&.
被称为Safe Navigator syntax,它允许您检查子属性,而不必对父母的存在进行笨拙的if检查。此行将显示updated_at
时间,或者如果它是nil
,则会显示no record
。
答案 1 :(得分:0)
element.pre_writings.ids.first
是一个整数值,它没有方法updated_at
也许你想写<%= element.pre_writings.first.updated_at %>
答案 2 :(得分:0)
您收到undefined method
错误,因为该方法是在nil上调用的。
您只能在updated_at
上致电pre_writing
,因此您需要确保先拥有<%= element.pre_writings.first.try(:updated_at) %>
。
然后你需要在实际对象而不是id上调用方法。
可以用类似的东西来完成
try
如果pre_writings.first
为零,则使用<% if @classroom.user_id == current_user.id && element.pre_writings.any? %>
<%= element.pre_writings.first.updated_at %>
可以防止错误。
或者您可以在if:
中添加支票 element
您可能还想将student
重命名为student
以提高可读性,因为它是pre_writings
,其中包含许多<div id="videoBox">
<video id="video" width="100%" controls loop>
<source src="some_url"></scource>
</video>
</div>
。