what should I define in application controller in ruby in rails? - ruby-on-rails

I don't know exactly why application_controller needs in ruby on rails
my idea is...
I had watched Ruby on Rails guide, I can find out route_not_found method is in application controller, and this method can used in other controllers.
so I thought application controller is different from normal controller, and this controller is for other controller.
def route_not_found
render file: Rails.public_path.join('404.html'), status: 404, layout: false
end
and method in application controller can be used as before_action's argument in other controller. I had defined not_login? method,
def not_login?
if current_user.nil?
redirect_to login_path, notice: 'You have to log in'
end
end
like this, and I can used this method in other controller as before_action's argument.
so I thought application_controller is for defining method which used for before_action.
is my thinking correct?
I want to know what application controller's true usage

Application controller helps abstract out shared logic of the controllers in your project. You can use it for various application wide tasks such as error handling, common methods, setting before actions, setting helper methods, etc.
As mentioned, methods that are used by multiple controllers can be placed here (ex. def current_user). However, if a method is only shared by a few controllers within a domain, it is better to place it into a different parent controller in that same domain to keep things organized.
In this example, the controllers would inherit from the custom parent controller and the custom parent controller would inherit from application controller.
You can set before actions in application controller and call them from application controller as well, just define the method and call before_action :method_name at the top of the application controller. That before action will run before all controller actions. If you only want it to run on certain controllers, then call it the way you described, just from the controller where you want it.

Related

How to execute a Ruby on Rails Engine's controller action from a Rails main app controller?

I have a Rails (4+) untypical usecase where one controller action needs to use the logic of another controllers action...
This question is related:
Rails: call another controller action from a controller
But its answers address only the case of redirection to another controller or delegating rendering to another controller, but I need to use some data transforming logic from the other controller and get the transformed results back to the calling controller...
Preliminaries:
My Rails application depends on several local Rails Engines, loaded in the main applications Gemfile with:
gem 'my_engine', :path => '../my_engine'
Those Engines implement an input-data transforming REST service with MVC and routes.
They use some of the models of the main application (for configuration), extend a base controller of the main app to have the same REST authorization like the main application etc...
Use Case:
Now my new use case needs me to use those engines controller actions inside of a main applications controller, to transform input data with those engines in a serial manner and return the transformed result for every execution back to the calling controller.
Pseudocode:
In main application: app/controllers/api/main_app_controller.rb:
class Api::MainAppController < ApplicationController
def index
result = params['data']
my_engines.each do |my_engine|
result = my_engine.execute_engine_controller_action(input)
end
render result
end
end
How do I have to change my Engines, to fulfill the new use-case and how do I execute those engines controller actions in a serial manner from a main applications controller?
Answer to myself:
You should out-source the data transforming logic from the Engine's controller into a helper of your Engine or in:
lib/my_engine/my_engine.rb
Then call this logic in the controller of the Engine and for the new use-case also in the main applications controller.

Call inner controller actions and send params between them rails

I'm creating an API and I want that the outside can only has access to update method to actualize a report. But in case there is no report I want to create it. I know that the easy way to do it is just create it inside update method, but as soon I have already a create method build I was wondering if is it possible to call it sending it also some params.
I looked around like here Rails 3: Call functions inside controllers or the API but I didn't found any good solution.
Does anyone has a better one?
Thank you very much in advance.
You should not call an action of your controller from another action.
Why? Because every action of a controller is defined to respond to a request, which has several attributes (such as IP, params, session, HTTP headers, etc.). Imagine how "weird" it would be to call an action from another in the Controller.
If you want to do "extra logic" which would not be related to the update action (for example, create), you should call a protected (accessible only via the Controller & its children) method of this controller.
In your case, you could do something like this:
class ReportsController < ApplicationController
def update
#report = Report.where(id: params[:report_id]).first
if #report.nil?
create_report(params)
else
# etc.
end
end
protected
def create_report(params)
Report.create(params)
end
end

Calling a Controller Action from a View... Or not?

I'll keep it short: Should I call Controller2.getByCriteria(some, criteria, here) from Controller1 then set an instance variable for the view to use, or should I call it from Controller1's view using something like = render Controller2.getByCriteria(some, criteria, here)?
Generally speaking, calling one controller's action from another is a design error. It either means you have common business logic, which implies the code should be in models (or maybe lib) or you have common view logic, which implies the code should be in helpers.
So in your case, I think using a helper seems apt:
module ApplicationHelper
# ...
def getByCriteria(some, criteria, here)
# handle criteria here
# Something like:
# render :partial => 'foo'
end
# ...
end
And then simply call it from the views.
If you want a full controller/view like component sharing across your application, you can use a gem called cells. It enables you to create re-usable controller and view components.
The proper way to do this is to declare the controller method (not controller action) as a helper.
See here.

Guidelines for calling controller methods in helper modules?

Few questions:
Is it possible to call a controller method in a helper module (e.g., application helper)?
If so, how does the helper handle the rendering of views? Ignore it?
In what instances would you want to call a controller method from a helper? Is it bad practice?
Do you have any sample code where you're calling controller methods in helper?
You generally don't call controller-methods from helpers. That is: if you mean a method that collects data and then renders a view (any other method that needs to be called should probably not be in a controller).
It is definitely bad practice and breaks MVC.
It is, however, perfectly possible to make controller-methods available in the views, a great example is for instance the current_user method.
To make a controller method available in the views, as a helper method, just do
private
def current_user
# do something sensible here
#current_user ||= session[:user]
end
helper_method :current_user
Such a method is best defined in the private section, or it could be available as an action (if you a wildcard in your routing).
Declare your methods on the corresponding controller
private
def method_name1
...
end
def method_name2
...
end
In the head of the controller declare
helper_method :method_name1, :method_name2
You may want to declare those methods under private state
And that's it, now you can use your method on a helper
Calling a controller from a helper violates the MVC pattern. IMO if you need to call a controller from a Rails view helper (like application_helper) then there is something about the design that could be improved. The intention is that helpers "help" views, and therefore only talk to models.
I'm not going to defend MVC itself here (there are a ton of references on the web), but this SO thread about calling the controller from a view should get you started.
Calling controller from view? (note, this is an ASP.NET thread, so only the high level principles are relevant).

IS there any application controller for .net mvc like ruby on rails?

I have some navigation things that need to hit the database every time a page has been requested. In Rails I would just set an instance variable in the ApplicationController.rb and that would be available to every controller/view.
Now I see that all my controllers inherent from : Controller in .NET MVC. Can I open a partial class for Controller and add an action filter that it would call every time a page is requested?
Or should I create an ApplicationController : Controller, and have all my other controllers inherit from that?
Controller is an abstract (not partial) class so you'll want to create a base controller class that extends Controller and have your controllers inherit from it. You can find the source code (for RC1 currently) at http://aspnet.codeplex.com/SourceControl/ListDownloadableCommits.aspx. Alternatively you can simply decorate your controllers with an appropriate custom ActionFilterAttribute, though my preference would be the custom base controller unless the filter needs to take parameters that differ for each controller.

Resources