2010-10-12 21 views
5

Tôi có khoảng 40 mẫu trong ứng dụng RoR của mình. Tôi muốn thiết lập một cuộc gọi lại after_save cho tất cả các mô hình. Một cách là thêm nó vào tất cả các mô hình. Vì cuộc gọi lại này có cùng mã để chạy, có cách nào để xác định nó trên toàn cầu một lần để nó được gọi cho tất cả các mô hình.Gọi lại toàn cầu ActiveRecord cho tất cả các kiểu máy

Tôi cố gắng này không có may mắn:

class ActiveRecord::Base 

    after_save :do_something 

    def do_something 
    # .... 
    end 
end 

Cùng đang hoạt động nếu tôi làm điều đó trong các mô hình cá nhân.

Cảm ơn, Imran

Trả lời

8

Bạn nên sử dụng các quan sát viên cho việc này:

class AuditObserver < ActiveRecord::Observer  

    observe ActiveRecord::Base.send(:subclasses) 

    def after_save(record) 
    AuditTrail.new(record, "UPDATED") 
    end 
end 

Để kích hoạt một người quan sát, liệt kê nó trong bối cảnh cấu hình config.active_record.observers trong cấu hình của bạn/ứng dụng. tập tin rb.

config.active_record.observers = :audit_observer 

Note

Trong Rails 4, tính năng quan sát được lấy ra từ lõi. Sử dụng đá quý https://github.com/rails/rails-observers.

+0

Tuyệt vời, cảm ơn! vì vậy tôi cần phải thêm tất cả các mô hình để "quan sát", phải không? Tôi hy vọng sẽ có cách tự động tìm nạp danh sách Mô hình và chuyển nó vào "quan sát"? Cảm ơn bạn lần nữa. – Saim

+0

Tôi vừa tìm thấy điều này: http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails- app – Saim

+0

Cập nhật câu trả lời của tôi, hãy xem. –

3

Tôi khá muộn về điều này, nhưng trong trường hợp người khác đang sử dụng Rails 3 và tìm thấy điều này, thì phản hồi này có thể hữu ích.

Một số mô hình có thể không được tải khi người quan sát được tải. Tài liệu nói rằng bạn có thể ghi đè các lớp được quan sát, và theo cách đó bạn có thể nhận được các lớp con của bản ghi hoạt động động.

class AuditObserver < ActiveRecord::Observer 
    def self.observed_classes     
    ActiveRecord::Base.send(:subclasses)  
    end 
end 
+0

Điều này thực sự thú vị, nhưng tôi khuyến khích sử dụng 'ActiveRecord :: Base.descendants' để tránh cuộc gọi phương thức riêng tư. – ludwigschubert

0

này thực sự hoạt động khá tốt cho tôi trong 2.3.8:

class AudiObserver < ActiveRecord::Observer 
    observe :'ActiveRecord::Base' 
    # 
    # observe methods... 
    # 
end 
1

này dường như làm việc cho tôi:

ActiveRecord::Base.after_save do 
    ... 
end 

Có một vấn đề Tôi không nhìn thấy?

Các vấn đề liên quan