2010-07-17 14 views
10

मैं रेल सीख रहा हूं, और थोड़ी सी समस्या में आया। मैं कार्यों की सूची के साथ मृत सरल अनुप्रयोग लिख रहा हूँ, इसलिए मॉडल है कि कुछ इस तरह दिखाई:रेल मॉडल में एकाधिक counter_cache

class List < ActiveRecord::Base 
    has_many :tasks 
    has_many :undone_tasks, :class_name => 'Task', 
          :foreign_key => 'task_id', 
          :conditions => 'done = false' 
    # ... some validations 
end 

के लिए तालिका List मॉडल कॉलम tasks_counter और undone_tasks_counter है।

class Task < ActiveRecord::Base 
    belongs_to :list, :counter_cache => true 
    # .. some validations 
end 

इस तरह के कोड के साथ वहाँ List उदाहरण के लिए attr_readonly :tasks_counter है, लेकिन मैं पूर्ववत कार्यों के लिए एक काउंटर के रूप में अच्छी तरह से करना चाहते हैं। रेल द्वारा स्वचालित रूप से कैश किए गए कई काउंटर होने का कोई तरीका है।

अब तक, मैंने TasksObserver बनाने में कामयाब रहा है जो Task#undone_tasks_counter में वृद्धि या कमी करता है, लेकिन शायद एक आसान तरीका है।

+0

क्या आपने इसे अंत में समझ लिया? –

उत्तर

19

क्या आपने इसे कस्टम-काउंटर-कैश कॉलम के साथ आजमाया है? यहां डॉक: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

यह पता चलता है कि आप counter_cache विकल्प पर जाकर अच्छी तरह से दो बार फोन करने के लिए जैसे

belongs_to :list, :counter_cache => true  # will setup tasks_count 
belongs_to :list, :counter_cache => :undone_tasks_count 

नोट सक्षम हो सकता है के लिए एक स्तंभ नाम पारित कर सकते हैं: वास्तव में परीक्षण नहीं किया।

+2

वास्तव में काम किया। कुछ समय के लिए एसओ खाते का इस्तेमाल नहीं किया, इस तरह के स्वच्छ समाधान के लिए धन्यवाद! –

+1

मैंने अभी यह कोशिश की और नतीजा दूसरा कैश दो गुना बढ़ रहा था और सबसे पहले नहीं। मुझे लगता है कि पिछले साल कुछ बदल गया? – Steven

+0

@ स्टीवन आप सही हैं। रेल एपीआई के मुताबिक, अब आप कॉलम का नाम निर्दिष्ट कर सकते हैं, इस प्रकार आपको एक अतिरिक्त कदम बचा सकते हैं। –

-1

मुझे इसके लिए किसी भी "automagical" विधि से अवगत नहीं है। पर्यवेक्षकों के लिए अच्छा लगता है, लेकिन मैं व्यक्तिगत रूप से मॉडल में कॉलबैक का उपयोग करना पसंद करता हूं (before_save, after_save)।

0

ez way।

1) पहला काउंटर - स्वचालित रूप से

2) मैन्युअल रूप से 'सही'

AnotherModelHere 

    belongs_to :user, counter_cache: :first_friends_count 


    after_create :provide_correct_create_counter_2 
    after_destroy :provide_correct_destroy_counter_2 

    def provide_correct_create_counter_2 
     User.increment_counter(:second_friends_count, another_user.id) 
    end 

    def provide_correct_destroy_counter_2 
     User.decrement_counter(:second_friends_count, another_user.id) 
    end 
-1

करना होगा सबसे शायद आप के रूप में यह रिवाज की स्थिति और साथ काउंटर संभाल कर सकते हैं, counter_culture मणि की आवश्यकता होगी न केवल बनाने और नष्ट करने के लिए काउंटर वैल्यू अपडेट करेगा, लेकिन अपडेट के लिए भी:

class CreateContainers < ActiveRecord::Migration[5.0] 
    create_table :containers, comment: 'Our awesome containers' do |t| 
    t.integer :items_count,  default: 0, null: false, comment: 'Caching counter for total items' 
    t.integer :loaded_items_count, default: 0, null: false, comment: 'Caching counter for loaded items' 
    end 
end 

class Container < ApplicationRecord 
    has_many :items, inverse_of: :container 
    has_many :loaded_items, -> { where.not(loaded_at: nil) }, 
      class_name: 'Item', 
      counter_cache: :loaded_items_count 
      # Notice that you can specify custom counter cache column name 
      # in has_many definition and AR will use it! 
end 

class Item < ApplicationRecord 
    belongs_to :container, inverse_of: :items, counter_cache: true 
    counter_culture :container, column_name: proc { |model| model.loaded_at.present? ? 'loaded_items_count' : nil } 
    # But this column value will be handled by counter_culture gem 
end 
संबंधित मुद्दे