经过一定时间后,Rails 更新数据库 [英] Rails update database after certain amount of time has gone by
问题描述
如果一本书是在 25 秒前创建的(部署时将是 7 天前,但我不能等那么久:)),我正在尝试更新我数据库中的列.
I am trying to update a column in my database if a book was created more than 25 seconds ago (when deploying, it will be 7 days ago, but I can't wait that long :)).
模型:
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...
Am I even close to getting this to work? What am I doing wrong? As you can see, I want to change the "queued" attribute to false after 25 seconds...
编辑
有人告诉我,我需要使用 Heroku 的调度程序之类的东西才能使其工作.如果没有类似的东西,有没有办法更新数据库?
I've been told I need to use something like Heroku's Scheduler for this to work. Is there no way for this to update the database without something like that?
推荐答案
您可以采取不同的方法.而不是有一个字段来知道它是否排队使用范围(对排队书籍的查询)
You could take a different approach. Instead of having a field to know if it' queued use a scope (a query for queued books)
class Book < ActiveRecord::Base
scope :queued, where('created_at <= ?', 25.seconds.ago)
scope :not_queued, where('created_at > ?', 25.seconds.ago)
end
所以现在在您的控制器中您可以执行以下操作:
So now in your controller you can do something like:
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
@book = Book.new
@not_queued_books = @user.books.not_queued
end
end
它是否解决了您的问题,还是您真的需要该列?因为有了范围,它完全可以工作,而且更加灵活和易于实施!
Does it resolve your problem or you really need to have that column? Because with a scope it totally works and it's away more flexible and easy to implement!
如果你想在默认情况下查看 not_queue Book.all
并且有一个范围来查看排队的,这里是一个例子
If you want to see the ones not_queue by default Book.all
and have a scope to see the queued ones here is an example
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
所以现在在您看来只需这样做:
So now in your view just do this:
<% @user.books.date_desc.each do |book| %>
请注意,现在默认范围是未排队的书籍,我也将排序移到了范围.当然,您可以在控制器中执行此 books.date_desc 应该更可取.
Notice now the default scope is books not queued and I moved the ordering also to a scope. Of course you can do this books.date_desc in your controller wich should preferable.
因此,正如您在评论中所说,您存在范围评估问题.嗯,这是因为范围在您启动应用程序时被缓存",所以 25.seconds.ago
将相对于您启动应用程序的时间,而不是从现在开始的 25 秒前想要.有很多资源可以解释这一点,如果你不明白我在说什么,你应该去查看它们.例如在这个 railscast http://railscasts.com/episodes/202-active-record-queries-in-rails-3
So as you said in the comment you have the issue of evaluation in scopes. Well, this is because the scope is "cached" when you start the app, so 25.seconds.ago
will be relative to the time you started the app instead of the 25 seconds ago from now as you want to. There are plenty resources explaining this, and you should go check them if you don't understand what I'm saying. For example in this railscast http://railscasts.com/episodes/202-active-record-queries-in-rails-3
那你该怎么办?您必须使用 lambda 包装您的范围,以便在您每次使用范围时都会对其进行评估,而不是在您启动应用程序时进行评估.
So what you have to do? You have to wrap your scopes with a lambda so it will be evaluated every time you use the scope instead of evaluating when you start the app.
像这样:
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 { ... }
{ ... }
Also instead of lambda { ... }
you can use the new 1.9 shorthand -> { ... }
instead
这篇关于经过一定时间后,Rails 更新数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!