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 变脏并允许其他控制器调用我的操作。

有解决代码重复问题的想法吗?

4

2 回答 2

1

你为什么不做一个单独的动作来接收一些额外的参数,比如msg?然后您可以利用内置的 I18n 支持:

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或者也许允许您返回一些消息以通知您是有意义的?

于 2012-07-08T14:11:51.590 回答
0

我认为这个解决方案没有什么太丑陋的地方。

要将逻辑限制在一个控制器中,您可以self.action_for在 PostController 中定义,而不是在 ApplicationController 中定义,并在其定义下方调用它。

请注意,您已经将第一个元素成对作为符号传递,因此不需要to_sym调用。action_for

于 2012-07-08T14:09:45.833 回答