Where to put a before_filter shared between multiple controllers
How about putting your before_filter and method in a module and including it in each of the controllers. I'd put this file in the lib folder.
module MyFunctions
def self.included(base)
base.before_filter :my_before_filter
end
def my_before_filter
Rails.logger.info "********** YEA I WAS CALLED ***************"
end
end
Then in your controller, all you would have to do is
class MyController < ActionController::Base
include MyFunctions
end
Finally, I would ensure that lib is autoloaded. Open config/application.rb and add the following to the class for your application.
config.autoload_paths += %W(#{config.root}/lib)
Laravel controller with multiple beforeFilter's
I ended up introducing a level parameter in the authorized groups. Then I only needed one single beforeFilter.
public function __construct()
{
$this->beforeFilter('userRole', ['on' => ['get', 'post', 'put', 'delete']]);
}
And the filter now lookes something like...
Route::filter('userRole', function ($route, $request){
$token = $request->header('X-Auth-Token');
// If the token doesn't exist the user isn't authenticated
if ($token === null) {
$data = ['Not authenticated'];
$code = 401;
$response = Response::json([
'error' => true,
'data' => $data,
'code' => $code
], $code
);
return $response;
}
// If the token is invalid the user isn't authenticated
else if ( ! isAuthenticated($token) ) {
$data = ['Not authenticated'];
$code = 401;
$response = Response::json([
'error' => true,
'data' => $data,
'code' => $code
], $code
);
return $response;
}
// If the user is not a member of group Admin s/he doesn't have access
if( ! isAuthorized($token, 'Admin') ){
$data = ['Not authorized'];
$code = 401;
$response = Response::json([
'error' => true,
'data' => $data,
'code' => $code
], $code
);
return $response;
}
});
And the isAuthorized method looks something like this.
public function isAuthorized($token, $group) {
$hasPermission = false;
$user = false;
$requiredGroup = false;
// Attempting to find the user will automatically throw errors if unsuccessful
try {
if( $group !== '*' ){
// Get the needed group
$requiredGroup = $this->groupProvider->findByName($group);
}
// Get the user, including the memberships
$user = $this->userProvider->findByToken($token);
} catch (InvalidTokenException $e) {
$hasPermission = false;
}
// If the group is '*' it means everyone has permission, but has to be authenticated!
// That's why we do this check after the token-check
if ( $group === '*' ) {
return true;
}
if( !$user || !$requiredGroup ) {
$hasPermission = false;
} else {
// Compare user permissions to required
foreach ($user['groups'] as $group) {
if( $group['level'] >= $requiredGroup['level'] ){
$hasPermission = true;
}
}
}
return $hasPermission;
}
rails newbie: how to set before_filter function for several application_controllers?
I resolve this by creating a new module in lob directory, then include it in both application controllers.
Multiple controllers with a single model
I would like to suggest you to not to $uses
statement. Instead of that you can use relations of the models like $this->Model->M0del1->....->someFunc();
if the relation exists.
If the relation between the models dos't exist then simply use $this->loadModel('ModelName');
in the specific function where-ever you need it.
If you use var $uses = array('Object');
it becomes global to the controller and it will load that model for all the actions of the controller despite of whether you require it or not. This will affect your performance.
If you use $this-LoadModel('ModelName');
in a particular function it will only load in that function not in all the actions.
Component and beforeFilter not loaded in controller when called from another controller
In that case there are few options
1. Use request Actions http://book.cakephp.org/2.0/en/controllers.html#Controller::requestAction
2. Move the logic or code you want to execute from SecondCrontroller to common component and use it in both contrllers.
3. Move the logic or code you want to execute from SecondCrontroller to AppController
cakephp how to have a controller class that other controllers extend
It will work fine. Controllers are nothing more than php classes, you can have them inherit any way you like, so long as Cake can find them.
- Create your ThingsController and place it in app/controllers/things_controller.php
- In your derived controller, add
App::import('Controller', 'Things');
above the class definition. - Define the class properly:
class TestController extends ThingsController {}
Filters will inherit like normal.
before_filter with devise
I would write a custom before filter that uses user_signed_in?
. This will just return a boolean, and not do any of the redirect-type actions that authenticate_user!
does.
So, you could write a before filter like this:
before_filter :custom_user_auth
...
def custom_user_auth
unless user_signed_in?
# Do custom stuff, ultimately restricting access to the
# ...protected resource if it needs to be
end
end
Do note that this before filter won't protect your resource from unauthorized users unless the inside area of that unless
statement redirects or renders.
Related Topics
Ruby: How to Check If a String Contains Multiple Items
Parsing Large Xml Files W/ Ruby & Nokogiri
Why Does a Simple Thin Server Stop Responding at 16500 Requests When Benchmarking
Many: 'Require': Cannot Load Such File -- "Gem_Name" (Loaderror) After Upgrade of Ruby/Rails
Rails 4: How to Upload Files with Ajax
How to Use the Fetch Method for Nested Hash
How to Round a Float to a Specified Number of Significant Digits in Ruby
Multiple Servers in a Single Eventmachine Reactor
How to Set Ca-Bundle Path for Openssl in Ruby
Paperclip File Not Found Error
Why Do Ruby Procs/Blocks with Splat Arguments Behave Differently Than Methods and Lambdas
How to Implement Yes/No Instead of Boolean for Certain Cases in Rails
Ruby Gems Won't Load Even Though Installed
You May Have Encountered a Bug in the Ruby Interpreter or Extension Libraries
How to Get the Destination Url of a Shortened Url Using Ruby