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 :)).
Models:
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
Controller:
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| %>
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…
Edit
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)
So now in your controller you can do something like:
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!
If you want to see the ones not_queue by default
Book.alland have a scope to see the queued ones here is an exampleSo now in your view just do this:
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.
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.agowill 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-3So 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.
Like this:
Also instead of
lambda { ... }you can use the new 1.9 shorthand-> { ... }instead