Rails在一段时间后更新数据库



我正在尝试更新数据库中的一列,如果一本书是在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

User show view:

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

我离成功还有一步吗?我做错了什么?正如你所看到的,我想在25秒后将"queued"属性更改为false…

编辑

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

您可以采用不同的方法。使用作用域(查询已排队的图书)

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

它解决了你的问题还是你真的需要那列?因为有了作用域,它完全可以工作,而且更灵活,更容易实现!


如果您想查看默认Book.all下的not_queue,并有一个查看队列的范围,这里是一个示例

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| %>

注意,现在默认作用域是books not queued,并且我将排序也移到了作用域。你当然可以做这些书。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

也可以用新的1.9简写-> { ... }代替lambda { ... }

相关内容

  • 没有找到相关文章

最新更新