2012-07-08 53 views
1

我有很多的重複代碼的控制器,如:軌道 - 乾涸的控制器操作

class PostController < ApplicationController 
    def action1 
    end 

    ... 

    def actionN 
    end 
end 

,基本上每個動作做這樣的事情:

def action 
    @post = Post.find(params[:id]) 
    if @post.action(current_user) 
    flash[:notice] = "#{custom string for this action}" 
    else 
    flash[:notice] = "Problem with your request" 
    end 
    redirect_to root_url 
end 

我想過ApplicationController中的一個方法,它接受一組符號並生成其他方法,例如:

def self.action_for(*args) 
    args.each do |method, string| 
    define_method method.to_sym do 
     @post = Post.find(params[:id]) 
     if @post.send method.to_sym 
      flash[:notice] = string 
     else 
      flash[:notice] = "Problem with your request" 
     end 
     redirect_to root_url 
    end 
    end 
end 

並調用PostController中:

action_for [:action1, "Congratulations!"], [:action2, "Cool action!"] .. 

我認爲這個解決方案是醜陋的,它使ApplicationController的髒,並允許其他控制器打電話給我的行動。

任何想法來解決代碼重複問題?

回答

0

我不認爲這個解決方案中有什麼太難看的東西。

要將邏輯限制爲一個控制器,您可以在PostController中定義self.action_for而不是ApplicationController,並在其定義之下調用它。

請注意,您已將第一個元素作爲符號配對,因此action_for中的to_sym調用不是必需的。

+0

謝謝dgutov,我想我會用你的解決方案。 – Andrea 2012-07-08 14:53:18

1

爲什麼你不做一個單一的動作,它會收到一些額外的參數,如msg?然後,你可以利用內置的國際化支持:

def some_action 
    @post = Post.find(params[:id]) 
    if @post.action(current_user) 
    flash[:notice] = I18n.t("messages.#{params[:msg]}", default: "Wrong message type") 
    else 
    flash[:notice] = I18n.t("messages.problem") 
    end 
    redirect_to root_url 
end 

或者,也許是有道理的,讓你的@post.action返回一些消息您的通知?

+0

謝謝jdoe, 問題在於調用「action1」控制器在模型上調用「action1」(並不總是相同的動作)。 E.g.有一個稱爲存檔的動作,稱爲@ post.archive,它將存檔我的文章。 無論如何,這明確解決了一個custum字符串的問題。 我有解決您的問題嗎? – Andrea 2012-07-08 14:39:37

+0

@Andrea沒注意到。但是你可以用'@ post.send' +'params [:msg]'來實現它,就像你之前做的那樣。只要確保惡意用戶不會觸發某些不允許的操作。 – jdoe 2012-07-08 14:53:55

+0

嗯,我會探討這個解決方案! – Andrea 2012-07-08 14:57:55