2012-07-08 50 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