最小化查询 - 从模型中排序结果

时间:2011-02-23 20:25:55

标签: ruby-on-rails ruby-on-rails-3

我有一个client has_many :tasks。我想将这些任务分类为单独的变量或散列,这些变量可用于我的视图,具体取决于它们到期的日期。

我正在尝试最小化查询,我知道此时我应该为客户端提取所有任务,然后将每个任务排序为变量。我可以在加载before_filter操作时使用控制器方法和show执行此操作:

 def build_client_tasks
    @tasks = client.tasks.due
    @tasks_today = []
    @tasks_tomorrow = []
    @tasks_upcoming = []
    @tasks_later = []
    for task in @tasks
      if task.due_date <= Date.today
        @tasks_today << task
      elsif task.due_date == Date.tomorrow
        @tasks_tomorrow << task
      elsif task.due_date > Date.tomorrow && task.due_date <= 7.days.from_now.to_date
        @tasks_upcoming << task
      else
        @tasks_later << task
      end
    end
  end

有更好/更聪明的方法吗?这工作正常,但如果我想在用户通过AJAX添加新任务时重新加载这些任务怎么办?然后,我被迫在我的* .js.erb文件中复制此代码,以便在重新加载任务部分时它们可用。

必须有更好的方法。在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

关于你的评论:我不会创建不同的数据库单元格。你应该只有一个具有due_date。然后你用这样的块做一个范围:

class Task&lt;的ActiveRecord ::基

scope :due_dated, lambda {|date| where(:due_date => date) }

然后你可以这样做:

Task.due_dated(Date.today)

嗨,史蒂夫, 您可能想尝试在任务/客户端模型中定义它。

class Task < ActiveRecord::Base

named_scope :today, :conditions => { :due => Date.today }

...

end

class Client < ActiveRecord::Base

def self.tasks_due_today
    tasks.today
end 

end

在你看来是这样的:

<%=  @client.tasks_due_today. each do |ct| %>
<li><%=  ct.content  %>
<%end%>

答案 1 :(得分:0)

我很想将此登录信息放入您的任务模型中:

class Task < ActiveRecord::Base
  # Returns upcoming tasks in a hash in the form:
  # { :today => [ task... ], :tomorrow => [ task...], :upcoming => [ task... ], :later => [ task... ] }
  def upcoming
    due.group_by do |t|
      if t.due_date <= Date.today
        :today
      elsif t.due_date == Date.tomorrow
        :tomorrow
      elsif t.due_date <= .days.from_now.to_date
        :upcoming
      else
        :later
      end
    end
  end
end

这样你就可以从任何地方做client.tasks.upcoming之类的事情了。例如。视图可能如下所示:

<% tasks = client.tasks.upcoming %>
<h2>Today's tasks</h2>
<%= render :collection => tasks[:today] %>
<h2>Tomorrow's tasks</h2>
<%= render :collection => tasks[:tomorrow] %>
<h2>Next 7 days</h2>
<%= render :collection => tasks[:upcoming] %>
<h2>Later</h2>
<%= render :collection => tasks[:later] %>

在Rails 3中,这将为列表中的每个任务呈现“_task.html.erb”部分的实例。

同样,您可以从.js.erb调用此方法,或者您可以使用.to_json从控制器返回此作为JSON,然后在客户端动态呈现它。