38

Tôi đang sử dụng tính năng xác thực trong ứng dụng của mình. Tôi đang tạo một nhóm người dùng mặc định bằng cách sử dụng tác vụ cào, nhưng mỗi khi tôi chạy tác vụ, một email kích hoạt được gửi đi vì người quan sát được liên kết với mẫu người dùng của tôi. Tôi đang thiết lập các trường kích hoạt khi tạo người dùng, vì vậy không cần kích hoạt.Cách đơn giản để tắt các nhà quan sát trong khi thực hiện nhiệm vụ cào?

Bất kỳ ai biết cách dễ dàng bỏ qua người quan sát trong khi chạy tác vụ cào để không nhận được email nào khi tôi lưu người dùng?

Cảm ơn.

Trả lời

7

Bạn có thể thêm một accessor để mô hình người dùng của bạn, giống như "skip_activation" rằng sẽ không cần phải được lưu lại, nhưng sẽ kiên trì thông qua phiên giao dịch, và sau đó kiểm tra cờ trong người quan sát. Một cái gì đó như

class User 
    attr_accessor :skip_activation 
    #whatever 
end 

Sau đó, trong quan sát:

def after_save(user) 
    return if user.skip_activation 
    #rest of stuff to send email 
end 
0

Không có một cách đơn giản để vô hiệu hóa các quan sát viên mà tôi biết, nhưng nó có vẻ thể thêm logic để quan sát viên của bạn để không gửi một email khi mã kích hoạt được thiết lập ...

2

Nhìn chung, cho các loại tình huống này, bạn có thể:

  1. Thiết lập một đối tượng giả để "hấp thụ" những hành vi không mong muốn
  2. có một lá cờ/switch bên ngoài truy cập rằng các quan sát viên tôn trọng để ức chế các hành vi
  3. Thêm Logic với người quan sát để dete ct khi hành vi không cần thiết là nói chung là (ví dụ: những gì dbarker gợi ý)
  4. Có một lá cờ toàn cầu "thử nghiệm", "gỡ rối", "khởi động" hay bất cứ điều gì mà
  5. nội quan thay đổi hành vi ở mức độ thấp và loại bỏ các nhà quan sát
  6. Thêm một phương pháp để mô hình của bạn mà thực hiện một sự thay thế , phiên bản unobserved của nhiệm vụ (chia sẻ thực hiện với các phương pháp bình thường càng nhiều càng tốt).

Trong trường hợp này, tôi muốn nói # 3 là đặt cược tốt nhất của bạn.

0

Như những người khác đã gợi ý; Tôi sẽ bọc logic không mong muốn trong Observer của bạn với một câu lệnh if đơn giản.

def after_create 
    send_email if RAILS_ENV == "production" 
end 
2

Khi kiểm tra chạy trên một ứng dụng tôi đang làm việc trên, tôi sử dụng như sau:

Model.delete_observers 
1

Bạn có thể lấy phương pháp người quan sát;

MessageObserver.send(:remove_method, :after_create) 

Sẽ dừng lại: after_create trên MessageObserver bằng cách xóa nó.

2

quan sát Vô hiệu hóa cho Rails 3 nó đơn giản:

Rails.configuration.active_record.observers = [] 
6

Một số khác bạn có thể thử (đường ray 3)

config.active_record.observers = :my_model_observer unless File.basename($0) == 'rake' 
+0

Điều này hoàn toàn giải quyết được vấn đề đối với tôi. Cảm ơn! – Sixty4Bit

+0

điều này cũng phù hợp với tôi !, nhưng tôi muốn thêm vào điều kiện bổ sung của ARGV [0] == "db: di chuyển" vì bạn có thể trong tương lai viết một nhiệm vụ rake sử dụng các nhà quan sát của bạn, và bạn có thể quên về dòng nhỏ này và kéo tóc của bạn cố gắng tìm ra lý do tại sao người quan sát của bạn không chạy trong nhiệm vụ cào mới lạ của bạn ... –

1

Tôi đến đây tìm kiếm một câu trả lời với cùng ... none của những điều trên dường như làm các trick (hoặc liên quan đến việc thêm logic di trú cụ thể vào mã ứng dụng của tôi - boo).

Đây là những gì tôi đã đưa ra (một chút què mà nó cần phải đi vào từng di cư có liên quan, nhưng ...)

class ChangeSomething < ActiveRecord::Migration 

    # redefine... 
    class MessageObserver < ActiveRecord::Observer 
    def after_create(observed) ; end 
    def after_update(observed) ; end 
    end 

    def self.up 
    # Message create/update stuff... 
    end 
end 
8

Như một lá cờ cho người quan sát tôi muốn định nghĩa một lớp được gọi là accessor "khuyết tật" để nó đọc như thế này:

class ActivityObserver < ActiveRecord::Observer 
    observe :user 

    # used in tests to disable the observer on demand. 
    cattr_accessor(:disabled) 
end 

tôi đặt nó như là một điều kiện trong callbacks nhạy cảm

def after_create(record) 
     return if ActivityObserver.disabled 
     # do_something 
end 

và tôi chỉ cần bật cờ trên khi cần thiết

ActivityObserver.disabled=true 
119

Rails 3.1 cuối cùng đi kèm với API cho việc này: http://api.rubyonrails.org/v3.1.0/classes/ActiveModel/ObserverArray.html#method-i-disable

ORM.observers.disable :user_observer 
    # => disables the UserObserver 

User.observers.disable AuditTrail 
    # => disables the AuditTrail observer for User notifications. 
    # Other models will still notify the AuditTrail observer. 

ORM.observers.disable :observer_1, :observer_2 
    # => disables Observer1 and Observer2 for all models. 

ORM.observers.disable :all 
    # => disables all observers for all models. 

User.observers.disable :all do 
    # all user observers are disabled for 
    # just the duration of the block 
end 

đâu ORM có thể ví dụ được ActiveRecord::Base

+0

Đây là câu trả lời hay nhất ở đây :-) –

+0

Cả hai đều không ngồi xổm cho tôi. Tôi đã kết thúc bằng việc biến chúng thành các nhiệm vụ cào trong application.rb – mhenrixon

+1

Hầu hết mọi người sẽ sử dụng gì thay cho 'ORM'? Ví dụ: –

1
User.skip_callback("create", :after, :send_confirmation_email) 

.... 

User.set_callback("create", :after, :send_confirmation_email) 

More về điều này:

Disabling Callbacks in Rails 3