Рельсы - СУХОЙ контроллер действия

У меня есть контроллер с большим количеством дублирования кода, таких как:

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 вернуть какое-то сообщение для вашего уведомления?

Другие вопросы по тегам