Ruby on Rails中调用模型timeline方法触发NameError的问题求助
解决Rails项目中Timeline方法调用的NameError问题
看起来你遇到的问题主要来自两个方面:视图中变量上下文的错误,以及模型方法的逻辑缺陷。让我们一步步解决:
1. 先修复视图中的NameError
你看到的undefined local variable or method 'pr_list'错误,本质是因为在index.html.erb视图里,你直接调用了pr_list.timeline,但视图中并没有名为pr_list的变量——控制器传给视图的是集合@pr_lists(从错误提示的Did you mean? @pr_lists也能看出来)。
你需要先遍历@pr_lists集合,才能在循环中拿到单个pr_list实例:
<%# pr_list/views/index.html.erb %> <% @pr_lists.each do |pr_list| %> <h1><%= pr_list.timeline %></h1> <% end %>
这样视图就能正确识别pr_list变量,调用它的实例方法timeline了。
2. 修正模型中的Timeline方法逻辑
你的原模型方法有几个问题:
- 每次循环都会覆盖
@timeline的值,最终只会保留最后一个已完成项的信息 - 在模型中使用实例变量
@timeline不合适,应该用局部变量来收集结果 - 还有一个拼写错误:
descrpition应该是description
修改后的模型方法应该这样写:
# app/models/pr_list.rb def timeline # 收集所有已完成的pr_item的描述和完成时间 completed_entries = pr_items.completed.map do |pr_item| "#{pr_item.description}: #{pr_item.completed_at.strftime('%Y-%m-%d %H:%M')}" # 可选:格式化时间更友好 end # 将数组拼接成字符串,用逗号或换行分隔都可以 completed_entries.join('<br>') # 如果要换行,用<br>;纯文本用', ' end
额外优化:给PrItem模型添加Scope
为了更优雅地获取已完成的项,建议在PrItem模型中添加一个scope:
# app/models/pr_item.rb scope :completed, -> { where(completed: true) }
这样pr_items.completed就能直接筛选出所有已完成的项,不用在循环里逐个判断pr_item.completed?了。
为什么直接写在视图里能运行?
当你把那段Ruby代码直接嵌在视图中时,肯定是放在了@pr_lists.each do |pr_list|的循环内部,此时视图处于pr_list的上下文里,自然能访问到该变量和它的pr_items。而把逻辑移到模型后,你忘记了在视图中正确遍历集合,才导致了变量找不到的错误。
内容的提问来源于stack exchange,提问作者Anuj Mohatkar
相关产品推荐
相关产品推荐

