Reputation: 19015
I am new to Ruby and new to Rails.
I have a method that queries two different data models, combines the results and returns the combined results
def combine_models
...
end
The method currently resides in a controller. I want to move the method to a module or class (still unsure which) so that the method can be used in multiple controllers.
1) Where is the best place to put this?
2) Should it be a module or a class?
3) What would the contents of the .rb file look like?
Currently I have it in /models/combine_class.rb
. The contents of the file are:
class CombineClass
def combine_models
...
end
end
The class appears to auto load, but to call the method I must use CombineClass.new.combine_models
.
4) Is that the proper way to call the method? Is there a way I could call the method without .new.
?
Upvotes: 0
Views: 113
Reputation: 1175
There's nothing actually wrong with leaving your class in the models directory although the newest Rails convention is to make it a concern.
If you only want the aggregate of some property of the two models and there isn't other behavior that your combination class is going to implement I would go with a simple solution like this.
class CombineFooAndBar
def self.combine_models(f, b)
f.x + b.y
end
end
class Foo
attr_accessor :x
end
class Bar
attr_accessor :y
end
f = Foo.new
f.x = 2
b = Bar.new
b.y = 3
puts "CombineFooAndBar value is #{CombineFooAndBar.combine_models(f,b)}"
If you need more behavior later then I would refactor it to a concern at that time.
Upvotes: 0
Reputation: 1771
I suggest to put in into the concerns folder of the model dir.
models/concerns/combine_models.rb:
module CombineModels
extend ActiveSupport::Concern
def combine_model1_model2
...
end
end
In your models you can include the module:
class Model1
include CombineModels
...
end
class Model2
include CombineModels
...
end
You can use your combine methods in every model, which includes the CombineModels module
Upvotes: 0
Reputation: 15781
I would recommend you to read this article: Structuring Rails Applications and extract your logic into app/usecases/model1_model2_combiner_usecase.rb
( app/models
isn't really a good place for this), which may look like this:
class Model1Model2CombinerUsecase
def self.run
...
end
end
Of course rename it properly, then just call it in your controller with
@combined_models = Model1Model2CombinerUsecase.run
Upvotes: 1