emi
emi

Reputation: 2950

Increment array index after rake task

So I've got an array of strings that I want to send to my Rails logger. What I want is after each rake task run, my index is incremented by one so that the next string is posts in the logger. I have tried this the traditional way of using class variables and using Redis. My index is refusing to increment. This is what I have tried.

TRY 1

accounts_controller.rb

class AccountsController < ApplicationController
  cattr_accessor :index
  @@index ||= 0

  def self.post
    current_user = User.find_by(:id => 1)
    user_posts = current_user.accounts.find_by(:id => 1).posts
    Rails.logger.info user_posts[@@index].tweet
  end
end

post.rake

desc 'send post to twitter'
task send_posts: :environment do
  AccountsController.post
  AccountsController.index += 1
end

In the second try I try to use Redis to make my @@index variable persistent. Still no increment.

accounts_controller.rb

class AccountsController < ApplicationController
  cattr_accessor :index
  @@index = $redis.set('index', 0)

  def self.post
    current_user = User.find_by(:id => 1)
    user_posts = current_user.accounts.find_by(:id => 1).posts
    Rails.logger.info user_posts[@@index.to_i].tweet
  end
end

post.rake

desc 'send post to twitter'
task send_posts: :environment do
  AccountsController.post
  #AccountsController.index += 1
  $redis.incr('index')
end

Can someone help me iterate over the array AFTER EACH rake task run?

Upvotes: 0

Views: 457

Answers (2)

Matouš Bor&#225;k
Matouš Bor&#225;k

Reputation: 15954

You must store the incremented value outside the rails code because Rails is genuinely loaded every time the rake task runs (the state is in no way preserved in between the rake runs). So, use the Redis approach.

Then, you can just use the incr method in your task, just as you already do. According to the documentation, incr will set the value under the key to 0 before incrementing, if the key does not exist.

Finally, do not set the value to 0 in your controller, otherwise you'll practically reset the value during each run of the rake task. Instead, use just get to get the current value from Redis:

class AccountsController < ApplicationController
  cattr_accessor :index
  @@index = $redis.get('index') || 0
end

And that should be it.

Upvotes: 1

toddmetheny
toddmetheny

Reputation: 4443

and why not just do all of that in a loop inside the rake task? why bother with incrementing that variable? You can put it all inside your rake task.

User.find_each do |user|
  user_posts = []
  user.accounts.each { |account| user_posts << account.posts }
  user_posts.each { |post| Rails.logger.info post.tweet }
end

Upvotes: 2

Related Questions