在我之前的学习项目中,我总是使用一个控制器,但现在我想知道这是好的做法还是总是可行的。
在所有RESTful Rails教程中,控制器都有show
,edit
和index
视图。如果授权用户已登录,则edit
视图可用,index
视图会显示其他数据操作控件,例如删除按钮或指向edit
视图的链接。
现在我有一个Rails应用程序完全属于这种模式,但index
视图不可重复使用:
现在我不知道如何处理这个案子。我能想到以下几点:
if
语句将视图拆分为两个大块/部分。index
和index_admin
。BookController
和BookAdminController
这些解决方案似乎都不完美,但现在我倾向于使用第三种选择。
这样做的首选方式是什么?
答案 0 :(得分:15)
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
时考虑管理员用户
我不确定是否有更好的方法,但这是我从目前为止所完成的十几个项目中学到的......
答案 1 :(得分:3)
我在这种情况下所做的事情最近发生了很大的变化。目前的方法如下:
我根据访问要求分离控制器。这让我很清楚 心智模型和检查访问控制(并测试它)的一种非常简单的方法。
我甚至将模型中的“您自己的访问权”分开 控制器。我通常也会保留控制器的名称 单独的命名空间。
这种方法也使得使用标准的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)
答案 2 :(得分:2)
如果有两个模块,请使用两个电流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
OR
class BookUserController < ApplicationController
def index_admin
render :action=>'index_admin', :layout => false
end
def index
end
end
答案 3 :(得分:1)
当我需要一个明确分开的管理区域时,我倾向于为一个资源寻找一个带有两个控制器的解决方案。管理员界面的admin / booksController中的Admin :: BooksController,包含所有操作和公共BooksController,根据需要只有索引和显示方法。