Reputation: 1527
Let's say I have a libraries controller and a books controller.
Part of libraries_controller.rb:
def report
#some code here
end
Part of books_controller.rb:
def create
@library.report
end
Is it possible to call another controller's method? If not, how do I make a library generate some sort of report after a book is created.
Upvotes: 0
Views: 903
Reputation: 1645
You do not want to create controller action that calls another controller action. This is possible (with, as Mohamad put it, ugly hackery), but will give you a lot of problems. The only really acceptable way to jump from one controller action to another is via redirect_to
, and that is not going to solve the problems you described.
In an MVC framework (such as rails), what you're going to want to do is move the reused parts of the report#create
action into the reprt model, and then reference this from both report#create
and book#create
. This could be a method like Report.define_report( my_params )
, or simply the existing Report.create()
method.
Behaviour such as what you described belongs in the Model. The Controller should simply be calling this, as the Controller's purpose is generally to set up the View.
References:
Upvotes: 1
Reputation: 32933
No, you can't call a different controller's method, and you shouldn't. You can, however, put methods into ApplicationController, which will mean they are inherited by all other controllers.
In your code, however, it looks like you're trying to call an instance method on a model object, assuming that's what @report
is, and that is not a controller method.
Upvotes: 1
Reputation: 35339
It's possible with ugly hackery, but you should not do that. You can issue a redirect to the other controller instead. You should pass along any params you need in the URL.
class BooksController < ApplicationController
def create
# ...
redirect_to report_library_path(param: :foo)
end
end
If you have functionality that should be shared. Say you want to generate a book report, for example, then you should extract this common functionality into a concern and mix it into the controllers.
# app/concerns/reports.rb
module Reports
extend ActiveSupport::Concern
def generate_report
# do stuff here
end
end
You can now mix this into your controllers and use the generate_report
method you wrote.
class BooksController < ApplicationController
include Report
def create
end
end
class LibrariesController < ApplicationController
include Report
def report
end
end
Upvotes: 1