module AdvertSelector class Banner < ActiveRecord::Base attr_accessible :comment, :confirmed, :start_time, :end_time, :frequency, :name, :placement_id, :target_view_count, :priority, :fast_mode, :helper_items_attributes belongs_to :placement, :inverse_of => :banners has_many :helper_items, :order => "position", :dependent => :destroy accepts_nested_attributes_for :helper_items scope :find_future, lambda { order('priority desc'). where('end_time > ? OR end_time IS NULL', Time.now). includes(:placement, :helper_items) } scope :find_current, lambda { find_future. where('start_time < ? OR start_time IS NULL', 1.hour.from_now). where('target_view_count IS NULL OR target_view_count > running_view_count') } # todo validates # validate placement def name_sym @name_sym ||= name.downcase.to_sym end def has_frequency? !frequency.nil? && frequency > 0 end def show_today_has_viewcounts?(current_view_count = nil) return true if target_view_count.nil? || fast_mode? current_view_count = running_view_count if current_view_count.nil? return false if current_view_count >= target_view_count @show_now_today_target ||= if target_view_count.nil? || end_time.nil? || end_time < 24.hours.from_now true else #view_count_remaining = target_view_count - current_view_count total_days = ((end_time - start_time)/1.day).round daily_view_count = target_view_count/total_days days_ending_today = ((Time.now.end_of_day - start_time)/1.day).ceil days_ending_today * daily_view_count end @show_now_today_target == true || current_view_count < @show_now_today_target end def show_now_basics?(use_time_limits = true) confirmed? && (!use_time_limits || start_time.nil? || start_time < Time.now) && (!use_time_limits || end_time.nil? || Time.now < end_time) && show_today_has_viewcounts? end def reload super reset_cache end def cache_key "AdvertSelectorBanner_#{id}" end def running_view_count counter = Rails.cache.read(cache_key).to_i counter = 0 if $advert_selector_avoid_cache counter = self[:running_view_count] if counter < self[:running_view_count] counter end def reset_cache Rails.cache.write(cache_key, nil, :expires_in => 2.weeks) @show_now_today_target = nil @name_sym = nil end def add_one_viewcount unless self.target_view_count.nil? counter = running_view_count + 1 Rails.cache.write(cache_key, counter, :expires_in => 2.weeks) self[:running_view_count] = counter since_update = running_view_count_change.last - running_view_count_change.first self.save if since_update >= 500 || counter >= target_view_count end end after_save :after_save_destroy_empty_helpers def after_save_destroy_empty_helpers helper_items.each do |hi| hi.destroy if hi.blank? end end end end