我有一个包含大量代码重复的控制器,例如:
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 :(得分: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
返回一些留言通知你是否有意义?
答案 1 :(得分:0)
我不认为这个解决方案有任何太难看。
要将逻辑限制为一个控制器,您可以在PostController中定义self.action_for
,而不是ApplicationController,并在其定义下面调用它。
请注意,您已经将第一个元素成对传递为符号,因此to_sym
中的action_for
次调用不是必需的。