Как организовать контроллер в умеренно большом Rails-приложении? - PullRequest
4 голосов
/ 12 июля 2010

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

Вот несколько вариантов, которые я рассматривал:

1) Пространство имен контроллеров. Так, например, есть каталог controllers / admin и каталог controllers / public. Это кажется привлекательным для организации, но также и надуманным, поскольку у одного ресурса часто могут быть действия, которые могут разумно принадлежать различным каталогам (например, действие show является общедоступным, тогда как действие create является admin). Так что это будет означать разделение некоторых моих ресурсов на два отдельных контроллера - один общедоступный, один админ. Кажется плохим.

2) Создание вложенных ресурсов. Я лишь изредка использовал вложенные ресурсы, поэтому мне не всегда понятно, когда лучше вкладывать ресурсы, а не просто передавать нужные данные через параметры явно. У кого-нибудь есть предложения / примеры того, как лучше всего использовать вложенные ресурсы? Когда это хорошая идея? Когда это перебор?

3) Просто оставьте стандартные контроллеры лесов в покое. Создайте новые действия коллекции / члена, где это необходимо, и используйте фильтры перед установкой разрешений для каждого контроллера Это кажется наиболее привлекательным, так как все просто. Но я немного нервничаю из-за того, что все в порядке, потому что некоторые контроллеры могут начать набухать от нескольких новых действий.

Если кто-то, имеющий опыт разработки больших приложений, мог бы предложить здесь некоторые рекомендации, он был бы очень признателен.

Ответы [ 2 ]

5 голосов
/ 12 июля 2010

Для организации наших приложений я сделал всего понемногу в зависимости от ситуации.

Во-первых, что касается отдельных контроллеров для функций администратора / пользователя, я скажу, что вы, вероятно, не хотите идти по этому пути. Мы использовали авторизацию и before_filter для управления правами в приложении. Мы катились самостоятельно, но 20/20 задним ходом, мы должны были использовать CanCan . Оттуда вы можете настроить что-то вроде этого (это псевдокод, реальный язык будет зависеть от того, как вы реализовали авторизацию):

before_filter :can_edit_user, :only => [:new, :create, :edit, :update] #or :except => [:index, :show]

protected

def can_edit_user
  redirect_to never_never_land_path unless current_user.has_rights?('edit_user')
end

Или на более высоком уровне

before_filter :require_admin, :only [:new, :create]

и в вашем контроллере приложения

def require_admin
  redirect_to never_never_land_path unless current_user.administrator?
end

Это зависит от того, какой маршрут, но я бы использовал его для авторизации вместо разделения контроллеров.

Что касается пространств имен и вложенных ресурсов, то это зависит от ситуации. В нескольких наших приложениях у нас есть оба. Мы используем пространства имен, когда есть причина для логического разделения или будут общие функции между группой контроллеров. Для нас важно и то, что мы помещаем административные функции в пространство имен, а внутри у нас есть пользователи, роли и другие собственные функции администратора.

map.namespace :admin do |admin|
  admin.resources :users
  admin.resources :roles
end

и затем внутри этих контроллеров у нас есть базовый контроллер, который хранит наши общие функции.

class Admin::Base < ApplicationController
  before_filter :require_admin
end

class Admin::UsersController < Admin::Base
  def new
   ....
end

Это обеспечивает нам логическое разделение данных и возможность немного подсушивать наш код, обмениваясь такими вещами, как before_filter.

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

map.resources :customers do |customer|
  customer.resources :tickets
  customer.resources :orders
  customer.resources :locations
end

и это дает нам URL:

customers/:id
customers/:customer_id/orders/:id
customers/:customer_id/tickets/:id

Другие преимущества, которые мы получили от этого, - это простота настройки систем меню и вкладок. Эти структуры хорошо подходят для организованного сайта.

Надеюсь, это поможет!

0 голосов
/ 12 июля 2010

Кроме того, похоже, что вложение ресурсов на глубину более одного уровня почти наверняка является плохой идеей:

http://weblog.jamisbuck.org/2007/2/5/nesting-resources

Да, это старая статья, но она имеет большой смысл для меня.

Если кто-то не согласен, я хотел бы услышать почему.

...