2010-07-03 21 views
9

Tôi đang làm việc trên một ứng dụng ruby ​​trên đường ray. Đối với một bộ điều khiển phiên, tôi muốn sử dụng một trường hợp để kiểm tra xem tài khoản của người dùng bị khóa hoặc bị cấm. Tôi đang cố gắng sử dụng đối tượng của một lớp như trường hợp, và sử dụng khi nào để kiểm tra các thuộc tính.Ruby on Rails Case/Switch. Làm thế nào để phù hợp với đối tượng?

Ví dụ,

user = Profile.find(1) 
case user 
when user.ban 
    redirect_to() 
when user.lock 
    redirect_to() 
else 
    redirect_to() 
end 

Vấn đề duy nhất là không hoạt động.

gì công việc là thế này:

case user.ban 
when true 
    redirect_to() 
else 
    redirect_to() 
end 

Bất kỳ lời khuyên về cách tôi có thể đi về kiểm tra nếu một đối tượng người sử dụng bị cấm hoặc bị khóa bằng cách sử dụng công tắc?

Cảm ơn bạn

Trả lời

19

Thực hiện một user.status phương pháp mà trả về một trạng thái của người dùng, sau đó bạn có thể làm điều này:

user = Profile.find(1) 
case user.status 
when "banned" 
    redirect_to() 
when "locked" 
    redirect_to() 
else 
    redirect_to() 
end 
+0

Cảm ơn bạn cho tất cả các câu trả lời. Tôi thấy câu trả lời của Zepplock hữu ích nhất cho ứng dụng của tôi. Sự khác biệt duy nhất là tôi đã sử dụng các biểu tượng trong phương thức và trường hợp. Dưới đây là phương pháp tôi đã viết: tình trạng def nếu self.ban trở lại: ban cuối nếu self.lock trở lại: khóa cuối cuối – Brian

+0

@ Brian: Chỉ cần để làm nổi lên vết đỏ một chút - nếu một hàm trả về một boolean, nó là hình thức tốt để đặt tên nó với một dấu chấm hỏi. Ngoài ra, mặc dù post-modifiers có thể bị lạm dụng và làm tổn thương mức độ dễ đọc, trong trường hợp này tôi nghĩ rằng họ làm việc để cải thiện nó: 'def status; return: bị cấm nếu bị cấm ?; return: bị khóa nếu bị khóa? end' – Amadan

0

bạn có thể làm như Zepplock nói. Nhưng đối với ví dụ sau đây là cách tốt nhất (chỉ là một ví dụ)

action_name = (user.ban)? "ban" : ((user.lock)? "lock" : "default") 
redirect_to(:action => action_name) 
13

Tôi thích câu trả lời của Salil; Tuy nhiên, nếu bạn thực sự thích case, bạn có thể làm điều này:

case true 
    when user.ban 
    redirect_to() 
    when user.lock 
    redirect_to() 
    else 
    redirect_to() 
end 

CẬP NHẬT Jörg nói việc này quá, và anh ấy là đúng! Cho anh ta một số phiếu bầu cho câu trả lời của anh ấy! (Như sẽ tôi)

case 
    when user.ban 
    redirect_to() 
    when user.lock 
    redirect_to() 
    else 
    redirect_to() 
end 

CẬP NHẬT 2012 này hoạt động bây giờ:

case user 
    when lambda(&:ban) 
    redirect_to() 
    when lambda(&:lock) 
    redirect_to() 
    else 
    redirect_to() 
    end 
end 
+0

+1 cho không bao giờ nghĩ đến việc sử dụng đúng như điều kiện trường hợp. – Salil

+0

Tôi đoán thứ tự của when s là khá quan trọng, phải không? Dù sao, 1 cho ý tưởng tuyệt vời như vậy. –

+3

Điều này là không cần thiết phức tạp. Lý do tại sao nó hoạt động là 'true === true' là không đúng. Nhưng hình thức khác của biểu thức 'trường hợp ', tức là chỉ đơn giản là bỏ qua' sự thật 'hoàn toàn, cũng vậy. –

0

@ Brian, ý tưởng về một trường hợp chuyển đổi là bạn có một biến mà chấp nhận một giá trị động và kiểm tra nó chống lại một vài tập hợp giá trị không đổi. Trong đoạn mã bạn đã viết, các câu lệnh case chứa các giá trị động như user.ban phụ thuộc vào chính biến mà bạn đang cố gắng kiểm tra. Cách chính xác để sử dụng trường hợp chuyển đổi là cách @Zepplock trình diễn.

2

Rất tiếc, tôi yêu câu trả lời của Amadan. Và nếu bạn thực sự muốn một tuyên bố trường hợp, có lẽ bạn nên làm những gì Zepplock nói (mặc dù có thể xem xét các biểu tượng thay cho chuỗi), nhưng dựa trên trường hợp sử dụng của bạn, bạn muốn có một giải pháp dựa trên if-statement, như Salil's.

Dù sao đi nữa, tôi nghĩ mình sẽ ném vào và vui vẻ quá^_^ Đây là giải pháp sẽ hoạt động với những gì bạn nói, nó tạo ra các đối tượng phản hồi === (trường hợp sử dụng câu lệnh), họ gọi phương thức quan tâm (khóa hoặc cấm) và trả lại nó. Có lẽ bạn nên đặt chúng vào một số loại cấu hình hoặc khởi tạo, hoặc nếu không lưu trữ các kết quả sau khi gọi đầu tiên, để tiết kiệm hiệu quả (ứng dụng của bạn chỉ cần để tạo ra các đối tượng này một lần)

user = Class.new do 
    def ban() true end 
    def lock() true end 
end.new 

def banned? 
    ban_checker = Object.new 
    def ban_checker.===(user) user.ban end 
    ban_checker 
end 

def locked? 
    lock_checker = Object.new 
    def lock_checker.===(user) user.lock end 
    lock_checker 
end 

case user 
when banned? 
    puts 'banned' 
when locked? 
    puts 'locked' 
else 
    puts 'default' 
end 

Lưu ý: Tôi 'không ủng hộ giải pháp này, bởi vì nó vi phạm đóng gói. Cấm phải được xác định và sử dụng trên người dùng của bạn, nhưng để thực hiện công việc này, nó phải được xác định trong phạm vi kèm theo.Tôi chủ yếu mang cái này lên cho vui :)

7

Chỉ cần bỏ qua user:

user = Profile.find(1) 
case 
when user.ban 
    redirect_to 
when user.lock 
    redirect_to 
else 
    redirect_to 
end 

Trong Ruby, có hai hình thức biểu hiện case. Trong biểu mẫu ở trên, nó chỉ thực hiện chi nhánh đầu tiên đánh giá thành giá trị không đúng (ví dụ: bất kỳ điều gì ngoại trừ nil hoặc false).

Các hình thức khác

case foo 
when bar 
    baz 
end 

tương đương với

if bar === foo 
    baz 
end 
Các vấn đề liên quan