Rails在经过一定时间后更新数据库

时间:2012-12-30 17:57:02

标签: ruby ruby-on-rails-3

如果超过25秒之前创建了一本书,那么我正在尝试更新数据库中的列(部署时,它将是7天前,但我不能等待那么长时间)。)。

型号:

class Book < ActiveRecord::Base
  attr_accessible :author, :date, :description, :order, :title, :user_id, :author, :status, :queued
  belongs_to :user
end

class User < ActiveRecord::Base
  attr_accessible :email, :password, :password_confirmation, :remember_me, :user_id, :name, :bio
  has_many :books
end

控制器:

class UsersController < ApplicationController

def show
  @user = User.find(params[:id])

  @book = Book.new

  @books = Book.select("DISTINCT name, id") # Not used right now

  @sequence = @user.books

  @sequence.each do |book|
    book.created_at >= 25.seconds.ago ? book.queued = false : nil
  end
end

用户展示视图:

<% @sequence.order("created_at DESC").where(:queued => false).each do |book| %>

我是否接近让这个工作?我究竟做错了什么?如您所见,我希望在25秒后将“排队”属性更改为false ...

修改

我被告知我需要使用像Heroku的Scheduler这样的工作。没有像这样的东西,没有办法更新数据库吗?

1 个答案:

答案 0 :(得分:1)

你可以采取不同的方法。而不是让一个字段知道它是否排队使用范围(对排队书籍的查询)

class Book < ActiveRecord::Base
  scope :queued, where('created_at <= ?', 25.seconds.ago)
  scope :not_queued, where('created_at > ?', 25.seconds.ago)
end

所以现在在你的控制器中你可以做类似的事情:

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])

    @book = Book.new

    @not_queued_books = @user.books.not_queued
  end
end

是否可以解决您的问题,或者您确实需要拥有该列?因为有一个范围它完全有效,它更灵活,更容易实现!


如果你想在默认情况下看到那些not_queue Book.all并且有一个范围可以看到排队的那个是一个例子

class Book < ActiveRecord::Base
  scope :queued, where('created_at <= ?', 25.seconds.ago)
  scope :not_queued, unscoped.where('created_at > ?', 25.seconds.ago)
  scope :date_desc, order("created_at DESC")
  default_scope not_queued
end


class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])

    @book = Book.new
  end
end

所以现在在你看来这样做:

<% @user.books.date_desc.each do |book| %>

现在请注意,默认范围是未排队的书籍,我也将排序也移到了范围内。当然你可以在你的控制器中做这本书.date_desc应该更好。


正如您在评论中所说,您在范围内有评估问题。好吧,这是因为当您启动应用程序时,范围会被“缓存”,因此25.seconds.ago将相对于您启动应用程序的时间而不是25秒前的相对于您想要的时间。有很多资源可以解释这一点,如果你不明白我在说什么,你应该去检查一下。例如,在此railscast http://railscasts.com/episodes/202-active-record-queries-in-rails-3

那你要做什么?您必须使用lambda包装范围,以便每次使用范围时评估范围,而不是在启动应用程序时进行评估。

像这样:

  scope :queued, lambda { where('created_at <= ?', 25.seconds.ago) }
  scope :not_queued, lambda { unscoped.where('created_at > ?', 25.seconds.ago) }
  scope :date_desc, order("created_at DESC")
  default_scope not_queued

而不是lambda { ... },您可以使用新的1.9简写-> { ... }代替

相关问题