Должен ли frontend и backend обрабатываться разными контроллерами?
в моих предыдущих учебных проектах я всегда использовал один контроллер, но теперь я задаюсь вопросом, является ли это хорошей практикой или даже всегда возможно.
во всех учебниках RESTful Rails контроллеры имеют show
, an edit
и index
вид. Если авторизованный пользователь вошел в систему,edit
вид становится доступным и index
вид показывает дополнительные элементы управления манипулированием данными, такие как кнопка удаления или ссылка на edit
вид.
теперь у меня есть рельсы приложение, которое попадает именно в этот шаблон, но index
просмотр не используется повторно:
- обычный пользователь видит кричащую индексную страницу с большим количеством изображений, сложным макетом, без требования Javascript ...
- пользовательский индекс администратора имеет совершенно другой минималистичный дизайн, таблицу jQuery и множество дополнительных данных ...
теперь я не уверен, как справиться с этим делом. Я могу думать о следующем:
- один контроллер, один вид: вид разделен на два больших блока/частичных с помощью
if
заявление. - один контроллер, два представления:
index
иindex_admin
. - два разных контроллерах:
BookController
иBookAdminController
ни одно из этих решений не кажется идеальным, но сейчас я склонен использовать 3-й вариант.
что это предпочтительный способ сделать это?
4 ответов
Я задавал себе этот вопрос почти каждый раз, когда я получаю новый проект. Обычно я выбираю одно из двух решений:
1). Один Контроллер, Один Вид
я почти никогда не выбираю это решение сейчас дней, если проект действительно прост, и только один или два типа пользователей. Если вы получаете несколько типов пользователей лучше использовать решение # 2. Хотя это решение может быть привлекательным, потому что вы думаете, что сэкономите время, написав меньше кода, но в в конце концов, ваш контроллер и представление будут расти в сложности. Не говоря уже обо всех крайних случаях, которые вы должны рассмотреть. Обычно это означает ошибки.
моей компании однажды пришлось спасать неудачный проект, у него было 3 типа пользователей. (администратор, бизнес и участник). Они использовали Решение № 1. Код был в ужасном состоянии ( и именно поэтому нас попросили спасти этот проект), мы в шутку говорили, что это не MVC, это был MMM. (Модель-модель-Модель) это потому, что бизнес-логика не была правильно извлечена и положенный в модели, но распространенный в регуляторах и взглядах также.
2). Несколько Контроллеров, Несколько Видов
Я использую это решение все больше и больше в эти дни. Я обычно пространство имен контроллеров с типами пользователей. Например:
в "app / контроллеры"
class BookController < ApplicationController
end
и в "app / контроллеры / admin"
class Admin::BookController < Admin::BaseController
end
мне нужно учитывать только обычных пользователей, когда я заполняю BookController, и только нужно учитывать пользователей admin, когда я заполняю Admin::BookController
Я не уверен, что есть лучшие способы, но это то, что я узнал из дюжины проектов, которые я сделал до сих пор...
то, что я делаю в такой ситуации, в последнее время немного изменилось. Нынешний подход заключается в следующем:
I отдельные контроллеры на основе требований доступа. Это дает мне ясность ментальная модель и очень простой способ проверить контроль доступа (и проверить его).
Я даже иду так далеко, чтобы разделить "ваш собственный доступ" к моделям на отдельные контроллер. Я также обычно храню имя контроллера, просто поместите его в отдельное пространство.
этот подход тоже делает его очень простым в использовании стандартный контроллер restuful реализации, такие как InheritedResources.
обратите внимание, что вы можете повторно использовать многие представления, если для различные виды доступа.
поэтому у меня было бы что-то вроде этого:
### lets start with routes
# this is basically guest access level. you can only list it and see details
map.resources :books, :only => [:index, :show]
namespace :my do |my|
# this will require at least login.
# index and show will be basically same as at the guest level. we can reuse the views
my.resources :books
end
namespace :admin do |admin|
# this will require admin login
admin.resources :books
end
# now the controllers
# this might be just enough of a controller code :). the rest goes into model.
class BooksController < InheritedResources::Base
actions :index, :show
end
module My
class BooksController < InheritedResources::Base
before_filter :require_user
protected
def begin_of_association_chain
# this will force resources to be found on current_user.books.
# so if you go to /my/books/123 and book 123 is not your book you will get 404
current_user
end
end
end
module Admin
class BooksController < InheritedResources::Base
before_filter :require_admin
# this controller is essentially unrestricted. you can get/edit/update any book
# and you can have separate view template for index too
end
end
## Views
# well, this is the part that I like the least in this approach, but
# I think the good outweight the bad.
# I see 2 ways to reuse the views w/o writing lots of ugly customization code for the InheritedResources
# 1) render 'parent' views inside templates. i.e. like:
# my/books/index.html.haml:
!= render :file => "/books/index"
# or just link the templates on the filesystem level with symlinks.
# (or if all of them are the same you can link the directory)
используйте два тока, если есть два модуля 1] Admin 2] User
сказать
class BookUserController < ApplicationController
#Here layout is used will be of layouts/application.html.erb
#Here all the methods which user can will be present
end
class BookAdminController < ApplicationController
layout 'admin' #here we set the layout is layouts/admin.html.erb
end
Если вы хотите показать только одну страницу администратора, вы можете использовать один контроллер и два метода
class BookUserController < ApplicationController
layout 'admin', :only=>['index_admin']
def index_admin
end
def index
end
end
или
class BookUserController < ApplicationController
def index_admin
render :action=>'index_admin', :layout => false
end
def index
end
end
когда мне нужна четко разделенная область администрирования, я, как правило, иду на решение с двумя контроллерами для одного ресурса. Admin:: BooksController в каталоге admin/ sub для интерфейса admin со всеми действиями и общедоступный BooksController, который имеет только index и show методы в зависимости от потребностей.