2010-07-03 30 views
9

我正在使用Rails應用程序的紅寶石。對於會話控制器,我想使用案例來檢查用戶的帳戶是否被鎖定或禁止。我試圖使用類的對象作爲案例,並使用何時檢查屬性。Ruby on Rails案例/開關。如何匹配對象?

例如,

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

唯一的問題是,不能正常工作。

是什麼工作是這樣的:

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

如何,我可以去,如果用戶對象是被禁止或鎖定使用開關檢查有什麼建議?

謝謝

回答

19

做一個user.status方法,它返回用戶的狀態,那麼你可以這樣做:

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

感謝您對所有的答覆。我發現Zepplock的答案對我的應用程序最有用。唯一的區別是我在方法和案例中使用了符號。下面是我寫的方法: DEF狀態 如果self.ban 回報:禁止 結束 如果self.lock 回報:鎖定 結束 結束 – Brian 2010-07-03 18:43:07

+0

@布賴恩:只是爲了Rubify一點 - 如果一個函數返回一個布爾值,用問號來命名它是一種很好的形式。此外,即使後修飾語可能會被濫用,並傷害易讀性,在這種情況下,我認爲他們會改進它:「def status;返回:如果禁止則禁止?返回:如果鎖定,鎖定?結束' – Amadan 2010-07-07 02:09:48

0

爲Zepplock說你可以做。但對於給出的例子以下是最好的方法(只是一個例子)

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

我喜歡@薩利爾的答案;但是,如果你真的很喜歡case,你可以這樣做:

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

UPDATE約爾格說,這個工程太,他是正確的!給他一些關於他答案的投票! (將我)

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

UPDATE 2012這現在工作:

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

+1永遠不會認爲使用真正的案件條件。 – Salil 2010-07-03 03:00:51

+0

我想when的順序非常重要,不是嗎?無論如何,+1這麼棒的主意。 – 2010-07-03 06:44:54

+3

這是不必要的複雜。這個原因爲什麼'true === true'是真的。但'case'表達的另一種形式,即完全忽略'true',已經做了同樣的事情。 – 2010-07-03 12:06:42

0

@布賴恩,一個開關盒的想法是,你必須接受一個動態值,並檢查它的變量反對幾個不變的價值觀。在您編寫的代碼片段中,case語句包含像user.ban這樣的動態值,這取決於您嘗試檢查的變量本身。使用開關盒的正確方法是@Zepplock如何演示。

2

大聲笑,我愛阿馬丹的答案。如果你真的想要一個case語句,你應該做Zepplock所說的(雖然可能會考慮符號代替字符串),但根據你的用例,你需要更多的基於if語句的解決方案,比如Salil's。

無論如何,我認爲我會投入並且有一些樂趣^ _^ 下面是一個解決方案,將與您所說的一起工作,它創建響應===的對象(使用什麼case語句),然後他們調用感興趣的方法(鎖定或禁止)並將其返回。你或許應該把它們放進某種配置或者初始化的,或者以其他方式存儲第一次調用後的結果,爲了節省性能(您的應用程序只需要創建這些對象一次)

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 

注:我不主張這個解決方案,因爲它是違反封裝。禁用應該在用戶中定義和使用,但爲了使其工作,它必須在封閉範圍內定義。我大多提起這事的樂趣:)

7

就離開了user

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

在Ruby中,有兩種形式的case表達。在上面的表格中,它只是執行第一個分支,該分支的計算結果爲非固定值(即除nilfalse之外的任何分支)。

另一種形式

case foo 
when bar 
    baz 
end 

相當於

if bar === foo 
    baz 
end