【发布时间】:2016-07-05 02:00:57
【问题描述】:
Order has_many AItems 和 BItems。如您所知,这些项目基本相同,但有一个重要的商业原因将它们分开分类。想知道干燥这个的最佳策略是什么。我意识到这有点自以为是……但希望能得到一些明确的观点和论据。
查看代码
目前我正在使用部分。像这样:
class AItemsController
def new
end
end
class BItemsController
def new
end
end
# view files layout
> views
> AItems
> new.html.erb
> BItems
> new.html.erb
# routing
get '/AItems/new'
get '/BItems/new'
# code for /views/AItems/new.html.erb
<%= render "layouts/items_new", object: "AItems" %>
# code for /views/BItems/new.html.erb
<%= render "layouts/items_new", object: "BItems" %>
我想知道完全摆脱部分是否更容易,只做这样的参数:
class AItemsController
def new
end
end
class BItemsController
def new
end
end
# view files layout
> views
> Items
> new.html.erb
# routing
get '/items/new/:type'
# code for /views/Items/new.html.erb
# code from partial evaluating the param[:type] instead of a passed object
控制器代码
目前所有内容都是重复的...(我还没有尝试过 DRYing),因为它看起来像这样(非常说明性,关键是要表明没有命名约定,实际上所有内容都基本相同):
class AItemsController
def new
@items = AItems.joins(:order).where("orders.status_id IS NULL")
end
def do_something
a_items_params.each do |item_params|
key_var = item_params[:some_attribute]
...
end
end
end
class BItemsController
def new
@items = BItems.joins(:order).where("orders.status_id IS NULL")
end
def do_something
b_items_params.each do |item_params|
key_var = item_params[:some_attribute]
...
end
end
end
我还没有把它弄干,因为我对如何做有点矛盾。下面的例子是说明性的,如果代码不准确,请原谅,但希望你能明白要点。
解决方案 A: 在一种方式中,我可以将动作定义保留在每个控制器中,然后将动作中的代码从共享关注点中提取出来:
class AItemsController
include SharedCode
def new
shared_new
end
def do_something
shared_do_something
end
end
解决方案 B: 将操作定义抽象为共同关注点:
class AItemsController
included SharedAction
shared_action("AItems")
end
解决方案 C: 将所有内容路由到单个控制器并再次使用参数来区分(从视图传递)
class ItemsController
def new
item_type = params[:item_type]
end
def do_something
item_type = params[:item_type]
end
end
型号代码
这个比较简单,在这里我不需要大量的反馈,我只是将共享关注点用于关键方法/回调。
显然,一个人的答案会影响另一个人。例如,如果所有内容都通过单个控制器进行路由,那么我将拥有一个带有参数的视图,而不是部分方法。但由于控制器有多个 DRYing 选项,因此仍有争论的余地。
如果您已经读到这里,我会很高兴地对这个问题的定义过于松散感到愤怒,以换取至少对您会做什么的一些想法。如果你接管了我的代码,你更容易理解什么?
我正在努力学习,而做到这一点的最佳方法是征求多种观点并权衡利弊。
【问题讨论】:
-
你可能使用继承,但为什么不使用一个项目表,只为 A 项目和 B 项目设置一个标签?
-
我同意上面的(单表继承)。但还有另一种选择:子类化 ItemsController。例如,使用解决方案 C,然后使用
AItemsController < ItemsController和例如定义要使用的项目类的私有方法 -
MageeWorld 将它们分开纯粹是商业原因,而不是代码原因。它使我们的会计更快/更容易。 TarynEast 我喜欢这个主意,好建议!
标签: ruby-on-rails ruby controller dry