经过一定时间后,Rails 更新数据库 [英] Rails update database after certain amount of time has gone by

查看:40
本文介绍了经过一定时间后,Rails 更新数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果一本书是在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆