如何只显示特定字段不为空的Rails记录?

时间:2012-03-05 16:50:55

标签: ruby-on-rails

我认为我在这里忽略了一些非常简单的事情,但我真的很感激帮助找出它是什么。

在项目展示视图中,我在部分中显示关联(has_many)任务。我只想显示特定字段不为空的记录。我的视图代码看起来像这样。

<% for task in @tasks %>
    <% unless task.user.notes.empty? %>
    <tr>
         <td><%= task.user.name %></td>
         <td><%= task.user.notes %></td>
    </tr>
    <% end %>
<% end %>

这将返回undefined method 'notes' for nil:NilClass。这很奇怪:注释肯定在用户模型中。

处理此问题的Project控制器包含:

def show
    @tasks = @project.tasks.paginate(:page => params[:page])
end

我的模型如下

Project
  has_many :tasks
end

Task
  belongs_to :project
  belongs_to :user
end

User
  has_many :tasks
end

我错过了什么?我正确使用empty?吗?或者我应该在控制器中处理这个?我目前在Project show上有三个部分,都使用相同的Task查询。性能和/或最佳实践方面,让所有三个部分从同一个控制器查询中获取数据,或仅针对这种情况进行特殊查询更有意义吗?

感谢您的任何指示。

2 个答案:

答案 0 :(得分:2)

在控制器中

def show
   @tasks = @project.tasks.paginate(
     :page => params[:page],
     :conditions=>["notes is not ? and notes !=?",nil,'']
   )
end

或,不在控制器中

编写一个帮助方法来抽象它。

添加新辅助方法

def filter_tasks(tasks)
  tasks.find(
    :all,
    :conditions=>["notes is not ? and notes !=?",nil,'']
  )
end

并在视图中使用帮助

<% for task in filter_tasks(@tasks) %>
  <% unless task.user.notes.empty? %>
    <tr>
      <td><%= task.user.name %></td>
      <td><%= task.user.notes %></td>
    </tr>
  <% end %>
<% end %>

答案 1 :(得分:2)

问题在于,当您致电User时,您的task.user.notes模型未定义。

您可以使用#delegateActiveSupport提供的Rails宏来解决此问题并改善整体设计。例如,在Task模型内部,尝试添加

delegate :notes, :to => :user, :prefix => true, :allow_nil => true

这会为task.user_notes模型添加Task方法,您可以直接从User本身获取notes的{​​{1}}。另外,因为我们指定了Task选项,如果没有与allow_nil关联的User,则该方法的结果将是Task而不是例外。

您还可以为nil的{​​{1}}属性添加此属性,以便您在视图中调用name

资源: