Reputation: 132
Right now I'm working on an app that takes an inventory file (csv), parses it, and persists it to a database. At first I was going to create an Inventory class that would parse the csv and also do business logic on the constructed Inventory database. But now it seems like I should be separating those concerns. The csv file will update daily, so parsing is an important part of the app.
So I'm now creating a class Feed to handle the inventory feed (.csv), parse it, check for errors, and maybe even act as a json endpoint. The only thing is, there is no need for this class to persist its data, the Inventory class will do that. So if this whole Feed class is a good idea, how would I include it in a Rails project? As a controller without a model? As a .rb file in /lib ? Should I be using rake tasks for this? Other options?
Upvotes: 1
Views: 101
Reputation: 1008
Here is how I would do it:
Create a rake task which reads the CSV file and writes it to the db
Install https://github.com/javan/whenever/blob/master/README.md
Configure whenever to execute your job in the desired interval
Add business logic if needed to the rake task or other "job" style class
Have your app simply read the results from the model
You could also use Resque or Sidekiq but that might be overkill for one simple task.
This way you have a "set and forget" setup and you can set whenever gem to take a look ever X minutes or so and don't have to worry about timing when the CSV comes in.
Clean separation of concerns and fully automated. Never read a CSV from a controller triggered action as you will block the thread for no good reason...
Upvotes: 1
Reputation: 3079
I think you should make class Feed in models folder. You can include several helper modules to add necessary functionality to the class.
class Feed
include ActiveModel::Validations # support validation
attr_accessor :file_name
validates :file_name, presence: true
def process
if valid?
...
end
end
end
Upvotes: 1
Reputation: 115541
Feed
could be an ActiveRecord model containing:
In your controller start a background job with the freshly created object responsible to process the file and update its status.
This way you can track all changes required and keep a history (or not, your choice to update status or destroy on success). But the point is background job sometimes fail and you need a solution for this.
As where to put the csv parsing code, I'd use a service object: since you're heavily dependant of your models I wont put this in lib (or maybe a part of the parse logic, but not the model creation)
Upvotes: 1