Рекомендации по повторному использованию кода между контроллерами в Ruby on Rails

У меня есть некоторые методы контроллера, которые я хотел бы поделиться. Какова наилучшая практика для этого в рубине на рельсах? Должен ли я создавать абстрактный класс, который расширяют мои контроллеры, или я должен создать модуль и добавить его в каждый контроллер? Ниже приведены методы контроллера, которыми я хочу поделиться:

def driving_directions
  @address_to = params[:address_to]
  @address_from = params[:address_from]
  @map_center = params[:map_center_start]

  # if we were not given a center point to start our map on
  # let create one.
  if [email protected]_center && @address_to
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_to).ll
  elsif [email protected]_center && @address_from
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_from).ll
  end
end

def printer_friendly
  starting_point = params[:starting_point].split(',').collect{|e|e.to_f}
  ne = params[:ne].split(',').collect{|e|e.to_f}
  sw = params[:sw].split(',').collect{|e|e.to_f}
  size = params[:size].split(',').collect{|e|e.to_f}
  address = params[:address]

  @markers = retrieve_points(ne,sw,size,false)
  @map = initialize_map([[sw[0],sw[1]],[ne[0],ne[1]]],[starting_point[0],starting_point[1]],false,@markers,true)
  @address_string = address
end

Ответ 1

По моему мнению, применяются обычные принципы проектирования OO:

  • Если код действительно представляет собой набор утилит, которым не нужен доступ к состоянию объекта, я бы подумал о том, чтобы включить его в модуль, который будет вызываться отдельно. Например, если код является всеми утилитами отображения, создайте модуль Maps и получите доступ к следующим методам: Maps::driving_directions.
  • Если код нуждается в состоянии и используется или может использоваться в каждом контроллере, введите код в ApplicationController.
  • Если код нуждается в состоянии и используется в подмножестве всех контроллеров, которые тесно и логически связаны (т.е. все о картах), затем создайте базовый класс (class MapController < ApplicationController) и разместите там общий код.
  • Если код нуждается в состоянии и используется в подмножестве всех контроллеров, которые не очень тесно связаны, поместите его в модуль и включите в необходимые контроллеры.

В вашем случае, методы нуждаются в состоянии (params), поэтому выбор зависит от логической связи между контроллерами, которые в ней нуждаются. Кроме того:

также:

  • Использовать частичные части, когда это возможно, для повторного кода и либо поместить их в общий каталог "partials", либо включить через определенный путь.
  • Придерживайтесь подхода RESTful, когда это возможно (для методов), и если вы обнаруживаете, что создаете много методов, отличных от RESTful, рассмотрите возможность их извлечения на свой собственный контроллер.

Ответ 2

Я знаю, что этот вопрос задавали 6 лет назад. Просто хочу отметить, что в Rails 4 теперь есть проблемы с контроллерами, которые являются более доступным из решения.

Ответ 3

На самом деле я считаю, что модуль - лучший способ совместного использования кода между контроллерами. Помощники хороши, если вы хотите поделиться кодами между представлениями. Помощники - это в основном прославленные модули, поэтому, если вам не нужен доступ на уровне уровня, я предлагаю разместить модуль в вашей папке lib.

Как только вы создадите модуль, вам нужно будет использовать оператор include, чтобы включить его в нужные контроллеры.

http://www.rubyist.net/~slagell/ruby/modules.html

Ответ 4

Я согласен с модульным подходом. Создайте отдельный файл Ruby в вашем каталоге lib и поместите модуль в новый файл.

Наиболее очевидным способом было бы добавить методы к вашему ApplicationController, но я уверен, что вы это уже знаете.

Ответ 5

если вы хотите обмениваться кодами между контроллером и помощниками, попробуйте создать модуль в библиотеке. Вы можете использовать @template и @controller для доступа к методу в контроллере и помощнике. Проверьте это для более подробной информации http://www.shanison.com/?p=305

Ответ 6

Другая возможность:

Если ваш общий код нуждается в состоянии, и вы хотите разделить поведение между контроллерами, вы можете поместить его в простой старый класс ruby ​​в вашем каталоге model или lib. Помните, что классы model не обязательно должны быть постоянными, хотя все классы ActiveRecord являются постоянными. Другими словами, приемлемо иметь переходные классы model.

Ответ 7

Я обнаружил, что один эффективный способ обмена идентичным кодом между контроллерами состоит в том, чтобы один контроллер наследовал от другого (где живет код). Я использовал этот подход для совместного использования идентичных методов, определенных в моих контроллерах, с другим набором контроллеров с именами.