0

I'm trying to find out a simple way for my task rake to locate users in the DB that have 0 days left from their created_at. Now so far I've been playing around with this, works great for single user but I want each user to be checked, if one or many are found with 0 days left... do something. Here's what I've got so far.

task :check_trial => :environment do
   def remaining_days
       users = User.all
       users.each do |user|
           ((user.created_at + 30.days).to_date - Date.today).round
       end
   end
   if remaining_days <= 0
      redirect_to http://www.google.com
   end
end

Not the cleanest, but either way the above isn't working for me. I'm not getting here something about the User.all. Anyone, please do assist and thank you in advance

user2419316
  • 331
  • 3
  • 15

3 Answers3

3

A better way is to fetch only those users that are expired from the DB. Write following method in User model

def self.expired_users
  where("created_at < ?", (DateTime.now - 30.days).beginning_of_day)
end

And in your Rake Task:

User.expired_users.each do |user|
 # do_something
end

Hope This helps :)

Himesh
  • 644
  • 3
  • 10
1

I would do something like this:

#user.rb

class User
  scope :expired, -> { where("created_at < ?", Datetime.now - 30.days) }

#rake task

task :check_trial => :environment do
  User.expired.each do |user|
    #something
  end
end

I am not entirely sure what you want to do with your rake task. The redirect is odd because you aren't in a browser. If you could explain what you are trying to achieve once you have all the expired users, I can help you out with that.

Sean
  • 983
  • 5
  • 13
0
  1. You need a method / query to pull a collection of all users with trials created over 30 days ago
  2. Your task should take this data, loop through & perform your activity on the individual records

--

Scope

You'll be best using a scope for the User model (as suggested in an answer already):

#app/models/user.rb
Class User < ActiveRecord::Base
   scope :expired, -> { where("created_at > ? ", 30.days_ago) }
end

This will allow you to select the users with the criteria of having a trial created over 30 days ago - as thus: @users = User.expired

--

Task

This will allow you to cycle through the expired trials as follows:

task :check_trial => :environment do
   def remaining_days
       for user in User.expired do
           ....
       end
   end
end
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • For loops are not ruby ish. It is preferred to use `.each` method from enumerable. – Sean Jun 01 '14 at 18:45
  • Thanks Sean! I'll keep that in mind, I prefer `for` because I find it easier to digest than `.each`: `for x in y do` vs `c.each do |y|` – Richard Peck Jun 01 '14 at 18:51
  • ah, but they are actually slightly different. take a look here. http://stackoverflow.com/questions/3294509/for-vs-each-in-ruby. using for can have some unintended side effects. – Sean Jun 01 '14 at 19:02
  • Ohh this is interesting! So `for` persists the local variable *after* the loop has finished? Thank you for this `Sean` - you do know `DHH` uses `for` in the Rails documentation? – Richard Peck Jun 01 '14 at 19:09
  • Also, where would you recommend the use of `for` over `each` – Richard Peck Jun 01 '14 at 19:11
  • I would say that in over 98% of occasions, you would want to use `each`, or `map`, or any of the methods in enumerable http://www.ruby-doc.org/core-2.1.1/Enumerable.html to work with collections. As stated, the only occasion I would really use a for loop in would be to persist the local var, but with the methods in the Enumerable module, most of the time I can get a simpler and more readable method, that is faster. Where in the rails docs does DHH use for loops? Just Curious to see the use case. Not to mention if its a simple case, using `to_proc` is really keeps the code clean and short. – Sean Jun 01 '14 at 21:02