在ruby(RoR)中从查询返回任何内容时,使用nils填充数组

时间:2013-09-24 05:54:41

标签: ruby-on-rails ruby haml

我有一个名为foo的模型,带有日期字段。

在我的索引视图中,我显示了指定周的典型“每周视图”。为了将数据放在我的视图中,我遍历指定周的每一天,并在一天中查询数据。我这样做是为了确保在正确的日子里放一个NIL。

foos_controller.rb

for day in 0..6
    foo = Foo.this_date(@date+day.days).first
    @foos[day] = foo
end

index.html.haml

- for day in 0..6
    %li
        - if @foos[day].nil?
            Create a new foo?
        - else
            Display a foo information here

显然,这里有很多错误。

  1. 我应该找一个聪明的成员来告诉我如何写一个好的查询,这样我只需要做一次。
  2. 我的观点中不应该有if / else
  3. 我的目标是要么显示特定日期的内容,要么显示“创建新”链接。

    感谢您的帮助!!

1 个答案:

答案 0 :(得分:3)

首先,我不知道this_date实际上做了什么,但我会假设它正在从您的数据存储区检索具有特定日期的记录。您可以使用日期范围将其压缩为一个查询,而不是执行7次查询:

Foo.where(date: (@date..(@date + 6.days)))

您可以使用.group_by(&:date)来返回类似于您手动构建的哈希的内容,但使用实际日期作为键而不是日期偏移量。

要迭代视图中的日期,我建议使用Hash#fetch,它允许您在键不存在时定义默认返回,例如:

hash = { :a => 1, :b => 2 }
hash.fetch(:a){ Object.new } #=> 1
hash.fetch(:c){ Object.new } # #<Object:...>

现在的问题是替换nil的对象。如果你想避免在这里使用条件,我建议你使用NullObject模式(你也可能涉及演示者,但这可能对你的情况有点过分)。这里的想法是你要创建一个新的类来替换丢失的foo,然后简单地在其上定义一个名为to_partial_path的方法,它将告诉Rails如何呈现它:

class NullFoo
  def to_partial_path
    "null_foos/null_foo"
  end
end

您需要在app/views/foos/_foo.html.erbapp/views/null_foos/_null_foo.html.erb创建部分,以定义每种情况下要呈现的内容。然后,在您的视图中,您可以简单地迭代:

<% (@date..(@date + 6.days)).each do |date| %>
  <%= render @foos.fetch(date){ NullDate.new } %>
<% end %>

这适合您的情况吗?也许这也有点矫枉过正,但总的来说,我认为养成尽可能避免零检查的习惯是个好主意。 NullObject的另一个好处是你可以在其上挂起各种行为,在整个应用程序中处理这些情况。