Yii2 - Url Manager - Specific rule failing - regex

I have the following url:
http://example.com/user/login
If I input the url in the browser, it matches de rule:
'<module:user>/<slug:[\w\-]+>' => '<module>/<slug>'
If I create the url:
Yii::$app->urlManager->createAbsoluteUrl(["user/index", "slug" => "login"]);
It should create the same url as above but instead it creates:
http://example.com/user/index?slug=login
But If I change the rule to:
'<module:user>/<slug:[\w\-]+>' => '<module>/index'
It works ok, any ideas why? I guess for some reason:
It is passing slug empty to or
It is an invalid value.
Any ideas?

That is because slug is part of the route pattern: '<module>/<slug>'. So <slug:[\w\-]+> is not treated as a named GET param, but as a part of the route. That means that URL /user/something will point to route user/something without any GET params.
You should not use the same name for route patterns and named params. You should either use different name:
'<module:user>/<action:[\w\-]+>/<slug:[\w\-]+>' => '<module>/<action>'
Or hardcode action for specified rule (as you already did in second example):
'<module:user>/<slug:[\w\-]+>' => '<module>/index'
Note that this will also match standard actions, like user/view.

Related

regex to validate router parameter not working

I want to validate if an email is being send correctly in routes, however it isn't working when I put a regex condition (like explained here)
Basically, I added:
Route::group([
'namespace' => 'Auth',
'middleware' => 'api',
'prefix' => 'auth'
], function () {
Route::post('login', 'AuthController#login');
// ...
Route::get('checkemail/{email}', 'AuthController#check_email')->where('email', '#.*?\.');
});
even if I pass a valid email I get an 404 not found. what can I do to make the code works well?
It looks like you're missing .+ before # in your regex.
Edit: I forgot to mention, you can put the same thing after #, and the current regex seems like it's wrong as well. I won't go into it, but validating email should not be complicated for a lot of reasons.

match route using a splat. What does it do?

I see this route:
match "*a", to: 'application#some_error_handler', via: :all
What does that do in Rails? Is that a splat "a"?
This is called route globbing and is explained in the Routing guide's section on route globbing:
Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example:
get 'photos/*other', to: 'photos#unknown'
This route would match photos/12 or /photos/long/path/to/12, setting params[:other] to "12" or "long/path/to/12". The fragments prefixed with a star are called "wildcard segments".
Wildcard segments can occur anywhere in a route. For example:
get 'books/*section/:title', to: 'books#show'

Redirecting a request in a routing constraint

I have Sidekiq mounted in my routes file to the /sidekiq endpoint.
I use a constraints option to have it call an external class for validation as a way of preventing non-privelaged users from accessing that endpoint.
# config/routes.rb
mount Sidekiq::Web => "/sidekiq", constraints: Sidekiq::AdminConstraint.new
# lib/sidekiq/admin_constraint.rb
module Sidekiq
class AdminConstraint
def matches?(request)
return false unless request.session[:user_id]
user = User.find_by_id(request.session[:user_id])
user && Ability.new(user).can?(:manage, :sidekiq)
end
end
end
This setup works great. However, it only lets me return true / false on whether the request should go through or not. It does not let me -
Set a flash message (e.g. "You are not permitted to access that page") and
Redirect to some arbitrary page
In that sense, I'm looking for it to behave more like a controller's before_filter.
Is there a way I can modify the request object that's passed in to implement that redirect?
Thanks!
I don't have idea directly set the flash messages, But we can use in different way.
Use the following solution
In your routes.rb, add the following line in the end of the file
match "*path", :to => "application#error_404"
This basically means, any path that is not defined in your route will end up going to error_404 in application_controller. Its very important to put this at the end of your file
And in your ApplicationController, add
def error_404
redirect_to root_path
end
Thanks

rails 4 - force two arguments in route

I would like to create url in 'routes.rb'.
I've got a resource 'Source', and source_controller that has 'index' method.
In order to reach 'index', I want the user to insert an url with two arguments like that:
source/{type}/{ids}/index
The code I wrote in routes works:
resources :sources, param: :types, :only => :index do
member do
get ':ids/index' => 'source#index'
end
end
It works, but is there a way to do it in more elegant way? (adding the ids to the resource somehow)

Why is my route not matching any action

Using play framework, I'm trying to match a route using a regular expression.
What I wanted is to use one action that maps all this urls:
mydomain.com/my-post-title-123
mydomain.com/another-post-title-124
mydomain.com/a-third-post-title-125
get this "123, 124 and 125" from the end of the url so the controller can use it. Basically ignore whatever post tile comes in and only use the number at the end.
I have the following on my routes.conf
GET /$postId<\d$> controllers.Posts.viewPost(postId: Int)
But I get the error page "Action not found"
You are missing the url prefix and "+" in the regex in the routes definition. Here is my route configuration and it works fine
#Regex test
GET /$prefix<.*>$postId<\d+$> controllers.Application.viewPost(prefix:String,postId: Int)
Controllers.Application.viewPost
def viewPost(prefix:String,postId:Int) = Action{
Ok("the post id is: "+postId+" the prefix is:"+prefix)
}
and the output will be
the post id is: 123 the prefix is "whatever/prefix/you/give"
** tested, it works.