Рекомендации по повторному использованию кода между контроллерами в Ruby on Rails - PullRequest
81 голосов
/ 24 сентября 2008

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

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's create one.
  if !@map_center && @address_to
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_to).ll
  elsif !@map_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

Ответы [ 7 ]

111 голосов
/ 25 сентября 2008

На мой взгляд, применяются нормальные принципы проектирования ОО:

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

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

Также:

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

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

15 голосов
/ 24 сентября 2008

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

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

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

1 голос
/ 02 июня 2010

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

1 голос
/ 24 сентября 2008

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

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

0 голосов
/ 09 апреля 2015

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

0 голосов
/ 26 сентября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...