[英]Calling a method in another class?
我在不同的命名空間(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
回答注釋中的一個隱式問題: 如果且只有該方法所屬類的調用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
獎勵軌道:在Rails中,可以使用Module#delegate
monkeypatch。
獎金軌道2:存儲為常量的proc的實現:
class A::TechnologiesController < ApplicationController
INDEX = -> { render json: Technology.all }
def index
INDEX.()
end
end
class B::TechnologiesController < ApplicationController
def index
A::INDEX.()
end
end
這是mixin的一個很好的例子。
有了它,您可以干燥您的代碼,而不必調用另一個控制器的方法。
這是模塊:
module CommonInterface
def render_technology
render :json, Technology.all
end
end
這將是您的控制器
class B::TechnologiesController < ApplicationController
include CommonInterface
def index
render_technology
end
end
如果您確實想弄干東西,那么祖先和mixin答案確實很好,但是我認為您不一定必須這么做。 render json:
位屬於控制器動作。 您希望您的操作能夠在兩個控制器中呈現某些內容。
查詢是一些可能以同樣的方式隨着時間的推移我想改變Technology.all
,所以你可以抽象的某個地方,但同樣,這可能是一個好主意,以觀望為主,如果是這樣的話。
如果確實使用mixins或基類,則可以將兩個控制器耦合在一起,這可能很好。 但同樣,您可能只想稍后再做出此決定。
您可以通過在ApplicationController中創建一個super方法來解決上述問題,並且需要在每個控制器中添加一個以上方法,以將值傳遞給不僅可以用於Technology模型的super方法,還可以將其用於任何其他模型。
舉個例子
在應用程序控制器中
class ApplicationController < ActionController::Base
def index
@collection = model
end
end
在每個控制器中,我們可以像這樣調用上面的方法
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中獲取的數據可以在視圖中使用,例如
對於app / views / students / index.html.erb
<% @collection.all.each do |student| %>
<tr>
<td><%= student.Name %></td>
<td><%= student.Email %></td>
</tr>
<% end %>
對於app / views / jobs / index.html.erb
<% @collection.all.each do |job| %>
<tr>
<td><%= job.id %></td>
<td><%= job.exp %></td>
</tr>
<% end %>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.