应该由不同的控制器处理前端和后端吗?

在我之前的学习项目中,我总是使用单个控制器,但现在我想知道这是好的做法还是总是可行的。

在所有RESTful Rails教程中,控制器都有一个show ,一个edit和一个index视图。 如果授权用户已登录,则edit视图变为可用, index视图将显示其他数据操作控件,如删除按钮或edit视图的链接。

现在我有一个Rails应用程序完全属于这种模式,但index视图不可重用:

  1. 普通用户看到一个华丽的索引页面,包含大量图片,复杂的布局,没有Javascript要求,……
  2. Admin用户索引具有完全不同的简约设计,jQuery表和许多其他数据,…

现在我不知道如何处理这个案子。 我能想到以下几点:

  1. 单个控制器,单个视图:使用if语句将视图拆分为两个大块/部分。
  2. 单控制器,两个视图: indexindex_admin
  3. 两个不同的控制器: BookControllerBookAdminController

这些解决方案似乎都不是完美的,但是现在我倾向于使用第三种选择。

这样做的首选方法是什么?

几乎每次我得到一个新项目时,我都会问自己这个问题。 我通常会选择以下两种解决方案之一:

1)。 单控制器,单视图

除非项目非常简单,并且只有一两种用户,否则我现在几乎从不选择此解决方案。 如果您获得多种用户类型,最好使用解决方案#2。虽然这种解决方案可能很有吸引力,因为您认为通过编写更少的代码可以节省一些时间,但最终,您的控制器和视图的复杂性会增加。 更不用说你必须考虑的所有边缘情况。 这通常意味着错误。

我的公司曾经不得不拯救一个失败的项目,它有3种用户类型。 (管理员,业务和成员)。 他们使用了解决方案#1。 代码处于可怕的状态,(这就是我们被要求拯救这个项目的原因)我们开玩笑地说它不是MVC,而是MMM。 (模型 – 模型 – 模型)这是因为业务逻辑没有被正确地提取并放入模型中,而是在控制器和视图中传播。

2)。 多个控制器,多视图

这些天我越来越多地使用这个解决方案。 我通常使用用户类型命名控制器。 例如:

在“app / controllers”中

 class BookController < ApplicationController end 

在“app / controllers / admin”中

 class Admin::BookController < Admin::BaseController end 

我只需要在填写BookController时考虑常规用户,并且在填写Admin::BookController时只需要考虑管理员用户

我不确定是否有更好的方法,但这是我从目前为止所完成的十几个项目中学到的...

我在这种情况下所做的事情最近发生了很大的变化。 目前的做法如下:

我根据访问要求分离控制器。 这给了我一个清晰的心智模型和一种非常简单的方法来检查访问控制(并测试它)。

我甚至将模型中的“您自己的访问”分离到单独的控制器中。 我通常也会将控制器的名称保存在一个单独的命名空间中。

这种方法也使得使用像InheritedResources这样的标准restuful控制器实现变得非常容易。

请注意,如果不同类型的访问需要相同的function,则可以重用许多视图。

所以我会有这样的事情:

 ### 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. ie 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 / books目录中的Admin :: BooksController,用于具有所有操作的管理界面和仅具有索引和显示方法的公共BooksController,具体取决于需要。