由于某些历史原因,在Rails项目中,Tiger
和Elephant
中的一段代码是相同的。
我不喜欢重复,但如果我在AnimalController
课程中创建新方法并将这些代码移入其中,我就无法return
walk
新方法中的{}或running
方法。
我认为从另一种方法返回可能不是一个好习惯,但我真的很讨厌重复,有人可以帮我重构吗?
class AnimalController
# I want create a new method here
#def all_in
#end
end
class TigerController < AnimalController
def running # This is an Action
some_different_codes...
if arm.blank?
render_not_found
return # <- how can I return `running` from the new method?
end
if lag.nil?
invalid_id
return # <-
end
some_different_codes...
end
end
class ElephantController < AnimalController
def walk # This is an Action
some_different_codes...
if arm.blank?
render_not_found
return
end
if lag.nil?
invalid_id
return
end
some_different_codes...
end
end
答案 0 :(得分:2)
如果不希望,方法无法使其调用者返回。所以这个新方法将执行检查(在渲染时),它将返回检查结果。调用方法分析返回值并决定要执行的操作。这些方面的东西:
class AnimalController
def all_in
if invalid_id
render_not_found
return false
end
if lag.nil?
invalid_id
return false
end
true
end
end
class TigerController < AnimalController
def running # This is an Action
some_different_codes...
return unless all_in
some_different_codes...
end
end
答案 1 :(得分:0)
可以好好查看callbacks和superclassing:
回调基本上允许您根据其他功能的响应在代码中运行登录。
因为我们将它们全部放在Rails上,所以没有多少人真正欣赏他们所做的事情。如果您曾经在JS中实现它们,那么您将了解它们的全部内容!
-
超级类别是您从现有类继承的地方 - 允许您使用(和扩展)该类具有的功能。这是 super 命令的来源。
我这样做(实际上看起来像Sergio
的答案,这是令人放心的):
#app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
private
def all_in?
if invalid_id
return false
end
if lag.nil?
invalid_id
return false
end
true #-> ruby automatically returns the last line
end
end
以上是您调用回调的内容 - 您可以调用all_in
(在实例中)并收到{{1} } response
或true
。
这将使您能够调用该方法(如果您false
,该方法将在链中可用:
superclassing
现在,您必须注意一些事情。
此类行为不应放在您应用的控制器中 - 它应该在您的模型中:
#app/controllers/elephants_controller.rb
class ElephantController < AnimalController
def walk # This is an Action
some_different_codes...
if all_in?
some_different_codes...
end
end
end
以上称为STI (Single Table Inheritance)。它基本上是一种使用其他&#34;依赖&#34;对主模型进行子类化的方法。模特儿他们的方法。
因为ruby是object orientated,所以你应该在对象本身上调用特定于对象的方法;
#app/models/animal.rb
class Animal < ActiveRecord::Base
def walk
end
end
#app/models/animals/elephant.rb
class Elephant < Animal
def walk
super ...
end
end
#app/models/animals/tiger.rb
class Tiger < Animal
end
这或多或少是state machine
:
#config/routes.rb
resources :tigers, :elephants, controller: :animals
#url.com/tigers/
#url.com/elephants/
#app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
def show
@tiger = Tiger.find params[:id]
@tiger.walk
end
end