Должен ли frontend и backend обрабатываться разными контроллерами?

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

во всех учебниках RESTful Rails контроллеры имеют show, an edit и index вид. Если авторизованный пользователь вошел в систему,edit вид становится доступным и index вид показывает дополнительные элементы управления манипулированием данными, такие как кнопка удаления или ссылка на edit вид.

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

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

теперь я не уверен, как справиться с этим делом. Я могу думать о следующем:

  1. один контроллер, один вид: вид разделен на два больших блока/частичных с помощью if заявление.
  2. один контроллер, два представления: index и index_admin.
  3. два разных контроллерах: 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 методы в зависимости от потребностей.