Rails RESTful 控制器与视图特定控制器
这个设计问题需要一些背景信息,所以请耐心等待。
我目前有三个模型,它们的结构如下:
class MyItem < ActiveRecordBase
has_many :my_list_items
...
class MyList < ActiveRecordBase
has_many :my_list_items
has_many :my_items, :through => :my_list_items
...
class MyListItem < ActiveRecordBase
belongs_to :my_item
belongs_to :my_list
has_many :my_list_item_properties
class MyListItemProperty < ActiveRecordBase
belongs_to :my_list_item
如您所见,MyListItem
模型不仅仅是一个简单的连接表,它还具有其他属性。
该应用程序中有两个主要视图。显示所有MyItems
,无论它属于哪个MyList
,并为它们提供标准的CRUD 操作。另一个视图显示一个 MyList
,其中包含来自其所有 MyListItems
以及每个关联的 MyItem
的数据。此视图允许对现有 MyItem
对象(通过 MyListItem
与列表关联)进行内联编辑,并允许内联表单创建新的 MyItem
对象和关联的MyListItem
。这些内联操作很大程度上依赖于分部和 RJS。
现在我有两个选择:
我可以使用控制器方法来促进例如在
MyItemController
和MyListController
中创建新的MyItem
,其中每个视图都对其关联的视图负责。这稍微违反了 DRY 原则,但它简化了渲染/重定向逻辑以及部分/RJS 与控制器操作的关联。或者我可以将
MyList
视图中的表单和 AJAX 链接提交到MyItemController
,然后后者必须小心地从MyList< 渲染部分或 RJS /code> 在适当的时候。这似乎也要求我指定一个 :controller => my_list 用于
MyList
相关视图中的每个 link_to_remote。这似乎是一种更 RESTful 的方法,并将MyItem
对象的创建限制为一个控制器,但它使控制器逻辑有些复杂。
您更喜欢哪种方法?为什么?
This design question needs a bit of context, so please bear with me.
I currently have three models that go something like this:
class MyItem < ActiveRecordBase
has_many :my_list_items
...
class MyList < ActiveRecordBase
has_many :my_list_items
has_many :my_items, :through => :my_list_items
...
class MyListItem < ActiveRecordBase
belongs_to :my_item
belongs_to :my_list
has_many :my_list_item_properties
class MyListItemProperty < ActiveRecordBase
belongs_to :my_list_item
As you can see, the MyListItem
model is more than a simple join table, it has other properties as well.
There are two main views in the application. One displays all MyItems
regardless of which MyList
it belongs to, and provides standard CRUD operations for these. The other view displays a MyList
, with data from all its MyListItems
and the associated MyItem
of each. This view allows inline editing to existing MyItem
objects (that are associated with the list via MyListItem
), and inline forms to create new MyItem
objects and associated MyListItem
. These inline actions rely largely on partials and RJS.
Now I have two options:
I can have controller methods to facilitate e.g., the creation of a new
MyItem
in bothMyItemController
andMyListController
, where each is responsible for its associated views. This is a slight violation of the DRY principle, but it simplifies rendering/redirect logic and the association of partials/RJS with controller actions.Or I can make the forms and AJAX links from
MyList
views submit toMyItemController
, which then has to take care to render partials or RJS fromMyList
when appropriate. This also seems to require me to specify a :controller => my_list for each link_to_remote inMyList
related views. This seems to be a more RESTful approach and limits the creation ofMyItem
objects to one controller, but it complicates the controller logic somewhat.
Which method do you prefer and why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我也经常和自己进行这样的辩论,我想我通常更喜欢选项#1。作为最佳实践,我们通常致力于精简控制器并寻找将初始化/创建逻辑分解到模型中的方法。在完美的世界中,操作中的大部分逻辑将是您将针对选项 #2 进行分支的视图特定渲染/重定向逻辑。
我还认为,随着时间的推移,不同视图的要求往往会有所不同:“我们希望在此页面上显示不同的闪存消息”。对于选项#2来说,这将是更多的分支。
在考虑了对模型合理的任何初始化逻辑并可能在控制器中使用常见的 before_filter 后,选项 #1 可能会感觉非常干净&干燥。
I often have this debate with myself also and I think I usually favor option #1. As a best practice we're usually striving for skinny controllers and looking for ways of factoring initialization/creation logic into the Model. In a perfect world, most of the logic in the action would be the view specific rendering/redirect logic that you'd be branching on for option #2.
I also feel the requirements tend to diverge over time for different views: "We'd like to show a different flash message on this page". Which would be just more branching for option #2.
After factoring any initialization logic that's reasonable to the model and maybe using a common before_filter in the controllers, option #1 would likely feel pretty clean & DRY.
我在这里最初的倾向是您的第一个建议选项,但使用 lib 模块(两个控制器都包含)来干燥围绕 MyItems 的任何重复代码或逻辑(当然,应该首先在 MyItem 模型中干燥) 。这使代码既简单又可维护。当您处理像这样的复杂 AJAX 设置时,代码逻辑简单的好处超过了严格的 RESTful 方法的好处。
My initial inclination here would be your first suggested option, but with a lib module (that both controllers include) to DRY up any duplicated code or logic surrounding MyItems (of course, as much as possible should by DRYed up in the MyItem model first). This keeps the code both simple and maintainable. When you're dealing with complicated AJAX setups like this, the benefits of code logic simplicity outweigh the benefits of a a strictly RESTful approach.