0
-module CachedValues # :nodoc:
0
- def self.included(base)
0
- base.extend(ClassMethods)
0
- # a very simple case in which cached_values works just like the .count method on a has_many association:
0
- # class Company < ActiveRecord::Base
0
- # caches_value :total_employees, :sql => 'select count(*) from employees where company_id = #{id}'
0
- # a more sophisticated example:
0
- # class User < ActiveRecord::Base
0
- # has_many :sales, :through => :trinkets
0
- # caches_value :remaining_trinket_sales_allotted, :sql => '... very complicated sql here ...'
0
- # user = User.find(:first)
0
- # user.remaining_trinket_sales_allotted # => 70
0
- # Trinket.delete_all # <= any operation that would affect our value
0
- # user.remaining_trinket_sales_allotted # => 70
0
- # user.remaining_trinket_sales_allotted.reload # => 113
0
- # You can also calculate the value in Ruby. This can be done by a string to be eval'ed or a Proc. Both are evaluated
0
- # in the context of the record instance.
0
- # class User < ActiveRecord::Base
0
- # caches_value :expensive_calculation, :eval => "some_big_expensize_calculation(self.id)"
0
- # caches_value :other_expensive_process, :eval => Proc.new {|record| record.other_expensize_process }
0
- def caches_value(name, options = {})
0
- reflection = create_cached_value_reflection(name, options)
0
- configure_dependency_for_cached_value(reflection)
0
- reflection.options[:cache] ||= reflection.name unless false == options[:cache]
0
- cached_value_accessor_method(reflection, ActiveRecord::CachedValue)
0
- cached_value_callback_methods(reflection)
0
- def configure_dependency_for_cached_value(reflection)
0
- if !reflection.options[:sql] && !reflection.options[:eval]
0
- raise ArgumentError, "You must specify either the :eval or :sql options for caches_value in #{self.name}"
0
- if reflection.options[:sql] && reflection.options[:eval]
0
- raise ArgumentError, ":eval and :sql are mutually exclusive options. You may specify one or the other for caches_value in #{self.name}"
0
- def create_cached_value_reflection(name, options)
0
- options.assert_valid_keys(:sql, :eval, :cache, :clear, :load, :reload)
0
- reflection = ActiveRecord::Reflection::MacroReflection.new(:cached_value, name, options, self)
0
- write_inheritable_hash :reflections, name => reflection
0
- def cached_value_accessor_method(reflection, association_proxy_class)
0
- define_method(reflection.name) do |*params|
0
- force_reload = params.first unless params.empty?
0
- association = instance_variable_get("@#{reflection.name}")
0
- if association.nil? || force_reload
0
- association = association_proxy_class.new(self, reflection)
0
- instance_variable_set("@#{reflection.name}", association)
0
- force_reload ? association.reload : association.load
0
- association.target.nil? ? nil : association
0
- def cached_value_callback_methods(reflection)
0
- %w{clear reload}.each do |operation|
0
- if events = reflection.options[operation.to_sym]
0
- events = [events] unless events.is_a?(Array)
0
- events.map! { |event| event.to_s }
0
- ActiveRecord::Callbacks::CALLBACKS.each do |callback|
0
- if events.include?(callback)
0
- send(callback, Proc.new {|record| record.send(reflection.name).send(operation)})
0
+require 'active_record'
0
+require File.expand_path(File.dirname(__FILE__) + "/cached_values/cached_value")
0
+require File.expand_path(File.dirname(__FILE__) + "/cached_values/cached_values")
0
+ActiveRecord::Base.send :include, CachedValues
Comments
No one has commented yet.