我在不同的命名空间(a和b)中有两个控制器,如下所示:
class A::TechnologiesController < ApplicationController
def index
render json: Technology.all
end
end
class B::TechnologiesController < ApplicationController
def index
render json: Technology.all
end
end
这两个动作执行相同的逻辑,我相信这是一个重复。我想消除重复,所以我如何借用下面的命名空间中的代码?
class B::TechnologiesController < ApplicationController
def index
A::TechnologiesController.method(:index).call self
end
end
答案 0 :(得分:3)
回答评论中陈述的隐含问题:如果且仅对象调用bind
is_a?()
实例,则可以使用UnboundMethod#bind
借用该方法方法所属的类:
def index
A::TechnologiesController.instance_method(:index).bind(self).()
end
但这既不惯用也不可读。一个人应该使用mixin:
module Mixins::TechnologiesController
def index
render json: Technology.all
end
end
class A::TechnologiesController < ApplicationController
include Mixins::TechnologiesController
end
class B::TechnologiesController < ApplicationController
include Mixins::TechnologiesController
end
或共同的祖先:
class Base::TechnologiesController < ApplicationController
def index
render json: Technology.all
end
end
class A::TechnologiesController < Base::TechnologiesController; end
class B::TechnologiesController < Base::TechnologiesController; end
Bonus track:在Rails中,可以使用Module#delegate
monkeypatch。
Bonus track#2:procs的实现存储为常量:
class A::TechnologiesController < ApplicationController
INDEX = -> { render json: Technology.all }
def index
INDEX.()
end
end
class B::TechnologiesController < ApplicationController
def index
A::INDEX.()
end
end
答案 1 :(得分:1)
这是mixin的一个很好的例子 有了这个,您可以干掉代码,而不必调用另一个控制器的方法。
这是模块:
module CommonInterface
def render_technology
render :json, Technology.all
end
end
这将是你的控制者
class B::TechnologiesController < ApplicationController
include CommonInterface
def index
render_technology
end
end
答案 2 :(得分:0)
如果你想干嘛,祖先和mixin的答案真的很好,但在我看来你并不一定要这么做。 render json:
位属于控制器操作。您希望您的操作在两个控制器中呈现内容。
查询可能会随着时间的推移以同样的方式发生变化我猜Technology.all
,所以你可以在某处抽象,但同样,等待并查看是否是这种情况可能是个好主意。
如果您使用mixins或基类,您将耦合两个控制器,这可能没问题。但同样,你可能只想稍后做出这个决定。
答案 3 :(得分:0)
您可以通过在ApplicationController中创建一个super方法来解决上述问题 并且您需要在每个控制器中添加一个方法以将值传递给super方法,您不仅可以将其用于技术模型,还可以将其用于任何其他模型。
样本示例
在应用程序控制器中
class StudentsController < ApplicationController
def index
super
end
def model
Student
end
end
class JobsController < ApplicationController
def index
super
end
def model
Job
end
end
在每个控制器中,我们可以像这样调用上面的方法
<% @collection.all.each do |student| %>
<tr>
<td><%= student.Name %></td>
<td><%= student.Email %></td>
</tr>
<% end %>
您将在@collection中收集的数据,可以在视图中使用,例如
对于app / views / students / index.html.erb
<% @collection.all.each do |job| %>
<tr>
<td><%= job.id %></td>
<td><%= job.exp %></td>
</tr>
<% end %>
对于app / views / jobs / index.html.erb
RewriteRule ^page-url/(*)?$ [R=404,L]