Hello Jong,
"Jong Hian Zin" <mail.zin@gmail.com> wrote:
>Hi Surendra,
>
>Thanks for the code. I guess I have to modify rails core, i.e.
>associations.rb associations/association_collection.rb and base.rb to add in
>the code, is that correct?
>
Nope, you don''t need to touch the rails core at all. Just add files in
the lib
folder and paste this code. You will be good to use it.
Ruby has this excellent facility which allows one to add functions to an
already existing class.
When I get more time, I will try putting up a blog entry explaining this
code.
Hope this helps.
--
Surendra Singhi
http://ssinghi.kreeti.com, http://www.kreeti.com
Read my blog at: http://cuttingtheredtape.blogspot.com/
,----
| "O thou my friend! The prosperity of Crime is like unto the lightning,
| whose traitorous brilliancies embellish the atmosphere but for an
| instant, in order to hurl into death''s very depths the luckless one
| they have dazzled." -- Marquis de Sade
`----
>
>On 3/14/06, Surendra Singhi <efuzzyone@netscape.net> wrote:
>>
>> Hello,
>> I needed to add custom cache field for one of my application. I thought
I
>> will share the code showing how to do this.
>>
>> This code below creates and maintain a custom cache field, for keeping
>> track
>> of totals. Say, you have accounts, and for each account there are
>> transactions
>> (either deposit/withdrawal), and one will like to keep track of the
total
>> balance for an account.
>>
>> So, let there be a transactions table with the field
''amount'' for which we
>> want
>> to keep track of the total. Then in the accounts table, we will need
the
>> field, ''transactions_total''.
>>
>> And while declaring the models just add the line,
>>
>> belongs_to_extra :accounts, :total_cache => :amount
>>
>> This code below is tested with edge rail, and will work for polymorphic
>> associations also.
>>
>> Any comments are welcome.
>>
>> module ActiveRecord
>> module Associations # :nodoc:
>> def self.append_features(base)
>> super
>> base.extend(ClassMethods)
>> end
>>
>> module ClassMethods
>>
>> def belongs_to_extra(association_id, options = { })
>> association_type = association_id.to_s + "_type" if
association_id
>> association_primary_key = association_id.to_s + "_id"
>> if options[:total_cache]
>> module_eval(
>> "after_create
>> ''#{association_type}.constantize.modify_value(\"#{
>> self.to_s.underscore.pluralize +
>>
"_total"}\",#{association_primary_key},#{options[:total_cache]})"
+
>> " unless
#{association_type}.nil?''"
>> )
>> module_eval(
>> "before_update
>> ''#{association_type}.constantize.modify_value(\"#{
>> self.to_s.underscore.pluralize +
>>
"_total"}\",#{association_primary_key},#{options[:total_cache]} -
>> #{self}.find(id).#{options[:total_cache]})" +
>> " unless
#{association_type}.nil?''")
>>
>> module_eval(
>> "before_destroy
>> ''#{association_type}.constantize.modify_value(\"#{
>> self.to_s.underscore.pluralize +
>>
"_total"}\",#{association_primary_key}_type,-#{options[:total_cache]})"
+
>> " unless
#{association_type}.nil?''"
>> )
>>
>> end
>> end
>> end
>>
>> class AssociationCollection
>> def total
>> count = if has_cached_total?
>>
@owner.send(:read_attribute,cached_total_attribute_name)
>> end
>> end
>> def has_cached_total?
>> @owner.attribute_present?(cached_total_attribute_name)
>> end
>> def cached_total_attribute_name
>> "#{@reflection.name}_total"
>> end
>> end
>> end
>> end
>>
>> module ActiveRecord #:nodoc:
>> class Base
>> class << self # Class methods
>> def modify_value(total_name, id, value)
>> update_all "#{total_name} = #{total_name} +
#{value}",
>> "#{primary_key} = #{quote(id)}"
>> end
>> end
>> end
>> end
>>