Рельсы - СУХОЙ контроллер действия
У меня есть контроллер с большим количеством дублирования кода, таких как:
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 и позволяет другим контроллерам вызывать мои действия.
Любая идея, чтобы решить проблему дублирования кода?
2 ответа
Я не думаю, что в этом решении есть что-то слишком уродливое.
Чтобы ограничить логику одним контроллером, вы можете определить self.action_for
в PostController, вместо ApplicationController, и вызовите его ниже его определения.
Обратите внимание, что вы уже передаете первые элементы в парах как символы, поэтому to_sym
звонит в action_for
не нужны
Почему бы вам не сделать одно действие, которое получит дополнительный параметр, например 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
вернуть какое-то сообщение для вашего уведомления?