Рекомендации по повторному использованию кода между контроллерами в 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
Я обнаружил, что один эффективный способ обмена идентичным кодом между контроллерами состоит в том, чтобы один контроллер наследовал от другого (где живет код). Я использовал этот подход для совместного использования идентичных методов, определенных в моих контроллерах, с другим набором контроллеров с именами.