2011-05-10 20 views
2

我經常建立控制器,我想要多種方法 (除了索引,編輯,顯示等)。大多數情況下,我想要的操作可能會被放在show中,因爲它們很簡單,GET操作, 但是我不想在任何一個控制器操作中放置太多的邏輯。控制器最佳實踐:顯示多個方法或多個案例

這是兩種不同的方法來達到同樣的事情 一個簡單的例子...

class TwitterFriendController < ApplicationController 
    ## lump everything into show? 
    def show 
    if params[:id] == "follow" 
     users = current_user.following 
    elsif params[:id] == "follow_me" 
     users = current_user.users_who_follow_me 
    elsif params[:id] == "following_follow_me" 
     users = current_user.following_who_follow_me 
    elsif params[:id] == "following_who_do_not_follow_me" 
     users = current_user.following_who_do_not_follow_me 
    ... 
    end 
    respond_with do |format| 
     format.json do {...} 
    end 
    end 

    ## or split everything out into separate methods, this requires 
additional routing 
    def following 
    ... 
    end 

    def users_who_follow_me 
    ... 
    end 

    def following_who_follow_me 
    ... 
    end 

    def following_who_do_not_follow_me 
    ... 
    end 
end 

一切都在顯示

  • 在一個方法
  • DRY一噸的邏輯?需要路由邏輯
  • 減#很多額外的代碼

單獨的方法

  • 多個路由
  • 不會幹
  • 簡易方法查找
  • 更易於讀取單個方法

所以再次真正的問題是,這些技術之一是更少 不好。

回答

6

我會做這樣的事情:

FOLLOW_WHITELIST = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ] 

def show 
    if FOLLOW_WHITELIST.include? params[:id] 
     users = current_user.send params[:id].to_sym 
    end 
    respond_with do |format| 
     format.json do {...} 
    end 
end 

這將調用任何方法在params爲傳遞[:編號],只要它在白名單(以防止任意代碼注入)。

如果有不同的途徑是加給你(更好的網址?),你也可以動態生成的方法和途徑有這樣的事情:

class TwitterFriendController < ApplicationController 

    FOLLOW_ACTIONS = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ] 

    FOLLOW_ACTIONS.each do |action| 
     define_method action do 
      users = current_user.send action.to_sym 
      respond_with do |format| 
       format.json do {...} 
      end 
     end 
    end 

end 

然後在routes.rb中:

FOLLOW_ACTIONS.each do |action| 
    match action.to_sym => "controller##{action}" 
end 
+0

美麗的解決方案 – bruno077 2011-05-10 20:10:56

+0

很優雅。然而,只要其中一種方法需要一些不能或不應該放入模型的額外邏輯,您就會失去所有的收益。我也不會在生產機器上的控制器方法上使用define_method,它在定義時保留了所有局部變量的範圍,並使用(稍微)更多的內存。如果任何人有任何額外的想法,我有興趣聽到之前我宣佈官方「答案」 – Schneems 2011-05-11 16:24:54

+0

我不知道你還等什麼其他類型的解決方案。一旦這些方法之一需要額外的邏輯,它不再反對「幹」原則有一個不同的方法。 – 2011-05-12 01:51:32