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