Лучшие практики контроллеров: несколько методов или несколько случаев в Show - PullRequest
2 голосов
/ 10 мая 2011

Я часто строю контроллеры, где мне нужно несколько методов (в дополнение к индексированию, редактированию, показу и т. Д.).Большую часть времени действия, которые я желаю, могли бы быть сведены к показу, поскольку они являются простыми операциями GET, однако я не хочу помещать слишком много логики в какое-либо одно действие контроллера.

Вот краткий пример двухразные способы достижения одного и того же ...

class TwitterFriendController < ApplicationController
  ## lump everything into show?
  def show
    if params[:id] == "follow"
      users = current_user.following
    elsif params[:id] == "follow_me"
      users = current_user.users_who_follow_me
    elsif params[:id] == "following_follow_me"
      users = current_user.following_who_follow_me
    elsif params[:id] == "following_who_do_not_follow_me"
      users = current_user.following_who_do_not_follow_me
    ...
    end
    respond_with do |format|
      format.json do {...}
    end
  end

  ## or split everything out into separate methods, this requires
additional routing
  def following
    ...
  end

  def users_who_follow_me
    ...
  end

  def following_who_follow_me
    ...
  end

  def following_who_do_not_follow_me
    ...
  end
end

Все в шоу

  • тонна логики в одном методе
  • СУХОЙ?# много дополнительного кода, необходимого для логики
  • Меньше маршрутизации

Отдельные методы

  • Больше маршрутизации
  • не DRY
  • Простой поиск методов
  • Легче читать отдельные методы

Опять же, вопрос в том, какой из этих методов меньше плох.

1 Ответ

7 голосов
/ 10 мая 2011

Я бы сделал что-то вроде:

FOLLOW_WHITELIST = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ]

def show
    if FOLLOW_WHITELIST.include? params[:id]
        users = current_user.send params[:id].to_sym
    end
    respond_with do |format|
        format.json do {...}
    end
end

Это вызовет любой метод, переданный в params [: id], если он находится в белом списке (для предотвращения произвольного внедрения кода).

Если наличие отдельных маршрутов было для вас плюсом (более хорошие URL?), Вы также можете динамически генерировать методы и маршруты с помощью чего-то вроде этого:

class TwitterFriendController < ApplicationController

    FOLLOW_ACTIONS = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ]

    FOLLOW_ACTIONS.each do |action|
        define_method action do
            users = current_user.send action.to_sym
            respond_with do |format|
              format.json do {...}
            end
        end
    end

end

А потом в route.rb:

FOLLOW_ACTIONS.each do |action|
    match action.to_sym => "controller##{action}"
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...