我有一些我想分享的控制器方法。在轨道上的红宝石中执行此操作的最佳做法是什么?我应该创建一个我的控制器扩展的抽象类,还是应该创建模块并将其添加到每个控制器?以下是我想要分享的控制器方法:
def driving_directions
@address_to = params[:address_to]
@address_from = params[:address_from]
@map_center = params[:map_center_start]
# if we were not given a center point to start our map on
# let's create one.
if !@map_center && @address_to
@map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_to).ll
elsif !@map_center && @address_from
@map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_from).ll
end
end
def printer_friendly
starting_point = params[:starting_point].split(',').collect{|e|e.to_f}
ne = params[:ne].split(',').collect{|e|e.to_f}
sw = params[:sw].split(',').collect{|e|e.to_f}
size = params[:size].split(',').collect{|e|e.to_f}
address = params[:address]
@markers = retrieve_points(ne,sw,size,false)
@map = initialize_map([[sw[0],sw[1]],[ne[0],ne[1]]],[starting_point[0],starting_point[1]],false,@markers,true)
@address_string = address
end
答案 0 :(得分:111)
在我看来,正常的OO设计原则适用:
Maps
,并访问以下方法:Maps::driving_directions
。class MapController < ApplicationController
)并将共享代码放在那里。在您的情况下,方法需要状态(params
),因此选择取决于需要它的控制器之间的逻辑关系。
另外:
此外:
答案 1 :(得分:32)
我知道这个问题是在6年前被问到的。只是想指出在Rails 4中,现在的控制器问题是一个更开箱即用的解决方案。
答案 2 :(得分:15)
我实际上认为模块是在控制器之间共享代码的最佳方式。如果您想在视图之间共享代码,那么助手是很好的。帮手基本上是美化模块,所以如果你不需要视图级别访问,我建议你在lib文件夹中放置一个模块。
创建模块后,您必须使用include语句将其包含在所需的控制器中。
答案 3 :(得分:1)
我同意模块方法。在lib目录中创建一个单独的Ruby文件,并将该模块放在新文件中。
最明显的方法是将方法添加到ApplicationController,但我相信你已经知道了。
答案 4 :(得分:1)
如果你想在控制器和助手之间共享代码,那么你应该尝试在库中创建一个模块。您可以使用@template和@controller来访问控制器和帮助器中的方法。 请查看此内容以获取更多详细信息http://www.shanison.com/?p=305
答案 5 :(得分:0)
另一种可能性:
如果您的公共代码需要状态,并且您希望在控制器之间共享行为,则可以将其放在model
或lib
目录中的普通旧ruby类中。请记住,即使所有ActiveRecord类都是持久的,model
类也不必是持久的。换句话说,拥有瞬态model
类是可以接受的。
答案 6 :(得分:0)
我发现跨控制器共享相同代码的一种有效方法是让一个控制器继承另一个(代码所在的位置)。我使用这种方法在我的控制器中使用另一组命名空间控制器共享相同的方法。