我目前有两个模型,大部分相似,但连接到不同的表
class MyModel1 < ActiveRecord::Base
...
def my_method
end
end
class MyModel2 < ActiveRecord::Base
...
def my_method
end
end
在许多地方,我有条件地获取数据,比如下面的
class MyController < ApplicationController
...
def my_action
item = my_condition ? MyModel1.find_by(code: 123) : MyModel2.find_by(code: 123)
result = item.my_method
end
end
class OtherModel < ActiveRecord::Base
...
def other_method(item_id)
resp = my_condition ? MyModel1.find_by(code: item_id) : MyModel2.find_by(code: item_id)
...
end
end
但要在所有地方保持这种检查方式变得非常困难。我该如何概括?我知道如果我们从父模型继承,那么子类将可以访问所有父模型方法
class MyGeneralClass < MyModel1
def initialize
super
end
end
item = MyGeneralClass.find_by(code: 123)
但我不知道如何在MyGeneralClass中添加检查,以便在其他地方调用所需的模型方法。低于
class MyGeneralClass
def initialize
klass = my_condition ? MyModel1 : MyModel2
klass.send(:private_instance_method)
end
end
item = MyGeneralClass.find_by(code: 123)
您只需在应用程序中添加一个简单的模块即可返回所需的记录,如下所示:
# in app/models/my_generic_model_finder.rb
module MyGenericModelFinder
def self.find_by(condition, query)
klass = condition ? MyModel1 : MyModel2
klass.find_by(query)
end
end
它可以用于您的控制器和类似的型号
MyGenericModelFinder.find_by(my_condition, code: 123)
另一种解决方案可能是只返回适合您的条件的正确模型,然后像使用普通模型一样运行所有查询。
# in app/models/my_conditional_model.rb
module MyConditionalModel
def self.for(condition)
condition ? MyModel1 : MyModel2
end
end
它可以用于您的控制器和类似的型号
MyConditionalModel.for(condition).find_by(code: 123)
因为MyConditionalModel.for(condition)
返回一个类,所以您也可以执行其他查询,如MyConditionalModel.for(condition).where(foo: 'bar').order(...)