Ruby on rails Rails从两个控制器调用相同的操作代码(略有不同)
我有两个不同的路线,需要输出相同的页面,只有微小的差异(标题,开放图形标签等) routes.rbRuby on rails Rails从两个控制器调用相同的操作代码(略有不同),ruby-on-rails,ruby,ruby-on-rails-3,url-routing,Ruby On Rails,Ruby,Ruby On Rails 3,Url Routing,我有两个不同的路线,需要输出相同的页面,只有微小的差异(标题,开放图形标签等) routes.rb match 'referral/:ref' => 'referral#home' root :to => "home#index" home_controller.rb class HomeController < ApplicationController def index @passion = Passion.new @workshop =
match 'referral/:ref' => 'referral#home'
root :to => "home#index"
home_controller.rb
class HomeController < ApplicationController
def index
@passion = Passion.new
@workshop = Workshop.new
@regions = Region.where("workshops_count > 0").order("name ASC")
@categories = Category.where("passions_count > 0 AND parent_id IS NULL").order("name ASC")
end
end
class HomeController0”)。订单(“名称ASC”)
@类别=类别。其中(“激情计数>0且父项id为空”)。顺序(“名称ASC”)
终止
终止
我不愿意将完全相同的代码从HomeController复制到ReferralController,也不希望重定向,因为title和OG标记必须不同(以便在共享页面时具有特殊的referral title)
使用express.js应用程序(我比较熟悉),我会在推荐路径中添加一个中间件,然后调用HomeController#index操作。因此,一切都将在路由级别完成
Rails中的惯用方法是什么
谢谢,
Laurent您可以在控制器操作中指定要渲染的模板/布局。例如,在
转诊#主页
控制器操作中:
render :template => 'home/index'
# app/controllers/home_controller.rb
def index
@stuff = HomeQuery.new
end
这假设控制器操作中没有太多逻辑(这是Rails中的最佳实践)
如果每个操作都有通用设置代码,则可以将其提取到模块中,并将其包含在两个控制器中:
module CommonFunctionality
def set_ivars
@passion = Passion.new
@workshop = Workshop.new
@regions = Region.where("workshops_count > 0").order("name ASC")
@categories = Category.where("passions_count > 0 AND parent_id IS NULL").order("name ASC")
end
end
class HomeController
include CommonFunctionality
def index
set_ivars
end
end
class ReferralController
include CommonFunctionality
def index
set_ivars
render :template => 'home/index'
end
end
这不是唯一可能的解决方案,Ruby中有许多抽象公共代码的方法。您可以指定要在控制器操作中呈现的模板/布局。例如,在
转诊#主页
控制器操作中:
render :template => 'home/index'
# app/controllers/home_controller.rb
def index
@stuff = HomeQuery.new
end
这假设控制器操作中没有太多逻辑(这是Rails中的最佳实践)
如果每个操作都有通用设置代码,则可以将其提取到模块中,并将其包含在两个控制器中:
module CommonFunctionality
def set_ivars
@passion = Passion.new
@workshop = Workshop.new
@regions = Region.where("workshops_count > 0").order("name ASC")
@categories = Category.where("passions_count > 0 AND parent_id IS NULL").order("name ASC")
end
end
class HomeController
include CommonFunctionality
def index
set_ivars
end
end
class ReferralController
include CommonFunctionality
def index
set_ivars
render :template => 'home/index'
end
end
这不是唯一可能的解决方案,Ruby中有许多抽象公共代码的方法。您可以创建一个helper方法,该方法执行所有公共操作步骤,然后从每个控制器操作调用该方法以使其干燥 因此,在
应用程序\u controller.rb中:
def setfoo
@foo = "setting foo"
end
然后在控制器操作中:
def oneaction
setfoo
end
def anotheraction
setfoo
end
要归功于这篇出色的文章,您可以创建一个helper方法,该方法执行所有常见的操作步骤,然后从每个控制器操作调用该方法以使其干燥
因此,在应用程序\u controller.rb中:
def setfoo
@foo = "setting foo"
end
然后在控制器操作中:
def oneaction
setfoo
end
def anotheraction
setfoo
end
这一杰出职位的功劳
我会在引用路由中添加一个中间件,然后调用HomeController#索引操作。因此,一切都将在路由级别完成
不要落入为了聪明而牺牲清晰度的陷阱。这可能是非常不直观和令人沮丧的人(包括你自己)进入您的项目在稍后阶段。这种方法也会受到一些任意决定的影响,比如哪个控制器动作被路由到哪个控制器
最好的代码是最简单的解决方案,它仍然可以清楚地将您的意图传达给读者。出于这个原因,我更喜欢尽可能使用普通的老Ruby对象。您可以将逻辑提取到简单的查询对象中,例如:
# app/queries/home_query.rb
class HomeQuery
attr_reader :passion, :workshop, :regions, :categories
def initialize
@passion = Passion.new
@workshop = Workshop.new
@regions = Region.where("workshops_count > 0").order("name ASC")
@categories = Category.where("passions_count > 0 AND parent_id IS NULL").order("name ASC")
end
end
然后使用它传递来自控制器操作的值:
render :template => 'home/index'
# app/controllers/home_controller.rb
def index
@stuff = HomeQuery.new
end
在您看来,您可以使用@stuff.passion
、@stuff.workshop
等访问您的资料
它是干的,它的意图是明确的,并且它使用了大多数人都熟悉的常见Ruby结构
我会在引用路由中添加一个中间件,然后调用HomeController#索引操作。因此,一切都将在路由级别完成
不要落入为了聪明而牺牲清晰度的陷阱。这可能是非常不直观和令人沮丧的人(包括你自己)进入您的项目在稍后阶段。这种方法也会受到一些任意决定的影响,比如哪个控制器动作被路由到哪个控制器
最好的代码是最简单的解决方案,它仍然可以清楚地将您的意图传达给读者。出于这个原因,我更喜欢尽可能使用普通的老Ruby对象。您可以将逻辑提取到简单的查询对象中,例如:
# app/queries/home_query.rb
class HomeQuery
attr_reader :passion, :workshop, :regions, :categories
def initialize
@passion = Passion.new
@workshop = Workshop.new
@regions = Region.where("workshops_count > 0").order("name ASC")
@categories = Category.where("passions_count > 0 AND parent_id IS NULL").order("name ASC")
end
end
然后使用它传递来自控制器操作的值:
render :template => 'home/index'
# app/controllers/home_controller.rb
def index
@stuff = HomeQuery.new
end
在您看来,您可以使用@stuff.passion
、@stuff.workshop
等访问您的资料
它很枯燥,意图很明确,并且使用了大多数人都熟悉的常见Ruby结构。请发布一些代码通常我们在瘦控制器Fat模型中使用rails,因此如果所有与模型相关的代码都与模型相关,那么就在模型中编写通用逻辑,并在这两个模型中调用controllers@ratnakar问题更新了一些代码。我理解瘦控制器/胖模型的事情,但这里我们实际上加载了“参考数据”(用于填充搜索过滤器等),请发布一些代码通常我们在瘦控制器胖模型中使用rails,因此,如果所有的代码都与模型相关,那么就在模型中编写通用逻辑,并在两者中调用controllers@ratnakar问题更新了一些代码。我理解瘦控制器/fat模型,但实际上我们正在加载“参考数据”(用于填充搜索过滤器等)。答案是将代码移动到应用程序。\u控制器更像是rails方式,我不会将此类代码放在应用程序控制器中,从应用程序控制器派生的所有控制器都可以使用特定于两个操作的代码是没有意义的。使用模块可以更好地对事物进行分类。答案是将代码移动到application_controller,这比rails way更重要。我不会将此类代码放在application controller中,因为特定于两个操作的代码对于从application controller派生的所有控制器都可用是没有意义的。