2013-06-15 27 views
6

Tôi là ứng dụng có số Post belongs_to :user Tôi muốn giữ lại bài đăng cho người dùng đã bị xóa. Điều này có thể gây ra lỗi trong chế độ xem khi xem bài đăng có tác giả đã bị xóa. Tôi đã cố gắng thực hiện điều này:Thực hiện mẫu NullObject trong Rails

class Post < ActiveRecord::Base 
    belongs_to :author, class_name: 'User', foreign_key: 'user_id' 

    def author 
    author || NullUser.new 
    super 
    end 
end 

Điều này gây ra lỗi 'xếp chồng lên mức sâu'. Tại sao? Tôi có thể làm điều này:

class Post < ActiveRecord::Base 
    belongs_to :user 

    def author 
    user || NullUser.new 
    end 

    def author=(user) 
    self.user = user 
    end 
end 

Nhưng có vẻ như không gây rối với các liên kết của tôi theo cách này. Cách tốt nhất để giải quyết vấn đề này là gì?

+3

Sidenote: Liên quan đến NullObjects và vừa xuất hiện, [vô] (https://github.com/avdi/naught) bởi Avdi Grimm. –

Trả lời

13

Để trả lời câu hỏi của bạn,

1. def author 
2. author || NullUser.new 
3. super 
4. end 

Trong dòng 1, bạn đang xác định một phương pháp author. Sau đó, trong dòng 2, bạn lại gọi phương thức tác giả đó! Điều này cứ tiếp tục xảy ra và bạn nhận được lỗi mức độ quá cao của ngăn xếp. Cách thích hợp để làm điều đó là,

def author 
    super || NullUser.new 
end 

Vì vậy, bạn không gọi lại phương pháp tác giả bên trong chính nó. Bạn chỉ đang gọi lớp siêu hoặc trở về NullUser. Trong trường hợp bạn nhận được một lỗi bằng không khi bạn đang gọi điện thoại super, sau đó thêm một kiểm tra nil thêm:

def author 
    (super || NullUser.new) rescue NullUser.new 
end 

Việc giải cứu tuyên bố sẽ bắt tất cả các lỗi và sau đó trở NullUser.new, vì vậy bạn không cần phải lo lắng về siêu ném một lỗi là tốt.

EDIT:

Một cách khác để xử lý siêu ném ngoại lệ mà trông đẹp hơn:

def author 
    (super rescue nil) || NullUser.new 
end 
2

Nếu bạn muốn giữ lại bài đăng cho người dùng đã bị xóa, tốt hơn là không thực sự "xóa" chúng.

Cách khác là "xóa mềm". Chỉ cần thêm một cột boolean nói "đã xóa" hoặc "không hoạt động".

Vì vậy, khi bạn định xóa người dùng, hãy kiểm tra xem anh ấy có bài đăng hay không. Nếu không có gì, khó xóa anh ta. Nếu có, xóa mềm.

Cách này sẽ đơn giản và sạch hơn nhiều.

Một cách khác là "ăn cắp" các bài đăng. Khi xóa người dùng, hãy di chuyển tất cả các bài đăng của mình trong tài khoản người dùng đặc biệt, sau đó xóa anh ấy.

Dù bằng cách nào bạn sẽ không phá vỡ liên kết.

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