开发者

Rake is trying to be too smart and discover endless loop before even triggering code

开发者 https://www.devze.com 2023-03-24 01:19 出处:网络
Today I was implepenting generator of random uniq strings for user (lets say something like a forgotten password token)

Today I was implepenting generator of random uniq strings for user (lets say something like a forgotten password token)

so I build up generator in *user_model*

  def generate_random_string
    random_string = CGI::escape( Base64.encode64(Digest::SHA1.digest("#{rand(1<<128)}/#{Time.now.to_f}/#{Process.pid}")))[0..12].downcase  #I was required it has to have max 12 chars
    if User.where( 'random_token_string = ?', random_string 开发者_JS百科)
     #if the string exist generate new one
     self.generate_random_string 
    else
      self.random_token_string = random_string
    end

    return random_string
  end

works 100% in console in application for one or for several users

than I builded up a RAKE task too update existing users

task :generate_random_string_for_existing_users => :environment do
  User.all.each do |user|
    unless user.vanity_name
      user.generate_random_string
      p "#{user.id} failed to be updated for some reason !!!" unless user.save!
    end
  end
end

from my point of view everithing ok

but when I run that rake

RAILS_ENV=development  rake generate_random_string_for_existing_users  --trace

I'm getting

rake aborted!
stack level too deep
/home/tomi/.rvm/gems/ruby-1.9.2-p290@project/gems/activerecord-3.0.1/lib/active_record/connection_adapters/abstract/quoting.rb:10

...nothing more nothing less. When I tried to run it from rails console it pass trought seccussfully

now when I coment out the recursion in the *user_model*

    #....
    if User.where( 'random_token_string = ?', random_string )
     #self.generate_random_string 
    else
    #....

...it will pass. So if I understand it correctly RAKE is trying to be smart even before the code is triggered. can anyone explain me why?


Justice's comment is right on the money -- instead, just do something like:

def build_random_string
    CGI::escape( Base64.encode64(Digest::SHA1.digest("#{rand(1<<128)}/#{Time.now.to_f}/#{Process.pid}")))[0..12].downcase  #I was required it has to have max 12 chars
end

def random_string_is_unique?(random_string)
    User.where(:random_tokent_string => random_string).count == 0
end

def generate_random_string
  # we'll loop until we find a unique code
  # it will execute build_random_string once before checking the while condition
  begin
    self.random_token_string = build_random_string
  end while random_string_is_unique?(random_token_string)
end
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号