1

Right now, I have a controller called Reports and inside of it I have a method called generate_pdf. When the user clicks the PDF icon, it routes to generate_pdf. Works fine.

However, now I am running a background task that needs to access the same code within generate_pdf from the Report controller.

How can I accomplish this? A redirect will not work because, again, it's a background process. Should I relocate this code elsewhere and just source it from there, or can I somehow just call the Report controller and past parameters? The end result of generate_pdf is rendering content to the user's web browser, but since this is a background task, I'm assuming it'll just return the content to whatever called it.

2
  • If generate_pdf is referenced from the Reports controller and from a background task, then perhaps a good place for it is in lib. Where is the background task defined? Your comment that you need the background task "to access the same code within generate_pdf from the Report controller." Is a little confusing. Do you mean the background task accesses the Report controller which, in turn, calls generate_pdf? Is Report different than Reports? If generate_pdf is only referenced from multiple controllers, then app/controllers/concerns would be a good place for it. Commented May 24, 2020 at 20:05
  • Hi @lurker Yes, I need the background task (a sidekiq worker) to access the generate_pdf method within the Reports controller. Sorry for the mixup between 'Reports' and 'Report' as well. it is just a single controller with a generate_pdf method that needs to be accessed by the user via the UI (just with a normal route that works properly) as well as a from sidekiq background worker. Commented May 24, 2020 at 20:11

2 Answers 2

3

There are probably a couple of ways of doing this. But one way would be to define generate_pdf in a lib file such as lib/pdf_tools/generate_pdf.rb. It would look something like:

module PdfTools
  def generate_pdf
    ...
  end

  ... # Other methods that support generate_pdf if needed
end

Then create a file config/initializers/pdf_tools.rb which contains:

Dir.glob("#{Rails.root}/lib/pdf_tools/*.rb").each do |file_name|
  require file_name
end

You can structure this in various ways to your liking. Rails will run the initializers automatically when the application starts. Creating the appropriate initializer should ensure that it is included in your controller and your background task.

Sign up to request clarification or add additional context in comments.

Comments

1

You should stay away from trying to use a controller action inside a background job or any other Rails class. That's not a good pratice.

In my opinion, a possible approach to solve this problem, would be to create a class ReportService (or something like that) and define there the generate_pdf method. This method would contain the common code should be shared between the controller and the background job. For instance, the render part of the content should still be done only in the controller.

# app/services/report_service.rb
class ReportService
  def generate_pdf
    # Inside here should be the common logic for the PDF generation
    # The result should in a suitable format in order to be able to be used by the controller and by the background job
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.