Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

route_to doesn't work for post routes #642

Closed
daylightstudio opened this issue Jul 29, 2017 · 12 comments
Closed

route_to doesn't work for post routes #642

daylightstudio opened this issue Jul 29, 2017 · 12 comments

Comments

@daylightstudio
Copy link
Contributor

daylightstudio commented Jul 29, 2017

I have an issue where I have a form in which I want to set the action to the post route using the route_to function. However, because the context of calling that route_to function is using the HTTPVerb that's not post, it doesn't find the route because they are excluded from the route collection. This seems like a common use case for using route_to.

<form action="<?=route_to('user/insert')?>" method="post">
...
</form>

Route Example:

$routes->post('admin/user/insert', 'UserController::insert', ['as' => 'user/insert']);
@lonnieezell
Copy link
Member

Well, damn, you're absolutely correct. Routing was one of the first items that was tackled, and the route_to function wasn't a twinkle in my eye just yet. :) I was ignoring any that weren't in the current method so there were fewer routes to have to parse, but it looks like we'll have to change that....

Any chance you want to make a PR for that?

@daylightstudio
Copy link
Contributor Author

Sure. The only thing I can think of as a fix is to simply remove HTTPVerb check which as you alluded to, may impact performance slightly.

@lonnieezell
Copy link
Member

Yup, that's exactly what I'd do. If we find it impacting performance we can refactor the matching process later.

@daylightstudio
Copy link
Contributor Author

Kind of a silly question, but how do you normally get the tests to run locally? I tried running phpunit in the root directory and nothing happens. Need to write a few for this update.

@lonnieezell
Copy link
Member

No worries. :) I install phpunit through Composer for this, since the Laravel projects I work on require different versions of phpunit. If it's installed that way, I always just do ./vendor/bin/phpunit from the root, because I'm too lazy to setup an alias. :)

@daylightstudio
Copy link
Contributor Author

daylightstudio commented Aug 2, 2017

I figured out my issues with running the test which had to do some modification I made to the Constants.php file which included other package Constants.

In thinking about this further, wont removing the HTTPVerb check potentially cause issues with GET/POST/DELETE routes with the same URI causing you to possibly get say the "DELETE" route when doing a "GET" request? Should we create a separate array that includes all created routes which the reverseRoute() method uses instead. Or should we do something with the $routes array by first indexing the route with the HTTPverb like so:

$this->routes[$this->HTTPVerb][$name] = [
	'route' => [$from => $to]
];

Or by prefixing the route with the verb:

$this->routes[$this->HTTPVerb . ':' . $name] = [
	'route' => [$from => $to]
];

The latter 2 would probably be a bit more work to fix stuff.

daylightstudio pushed a commit to daylightstudio/CodeIgniter4 that referenced this issue Aug 3, 2017
@lonnieezell
Copy link
Member

I think the way you did it works great. My initial concern was the resources taken up by the potentially empty arrays for the methods, since arrays used to be fairly expensive. I've seen some blog posts by Blackfire.io that show that these packed arrays are much cheaper in PHP 7.

@daylightstudio
Copy link
Contributor Author

Actually, after thinking about this implementation more, we could potentially have an issue if a route with the same URI uses add (which uses "*" array key) and another route uses say post and is declared before the add route. The add route would always be overwritten regardless of when it was added in the order because of the array_merge order. This is the line:

$collection = array_merge($this->routes['*'], $this->routes[$verb]);

I'm now thinking the string prefix approach may be better here. I'll work on it and send in a pull request for you to review.

@daylightstudio
Copy link
Contributor Author

I got pretty far on the string prefix implementation but am having second thoughts now. The implementation I'm working on is giving me issues with named route lookups which are putting me down a smelly code alley that may not be worth it. The pull request array implementation just puts more importance on routes with a verb which may actually be better anyway.

@lonnieezell
Copy link
Member

It seems to me that one with a specific method should normally override the wildcard version. Though, if someone waned to take the easy way and use add to handle a couple of different verbs to the same controller/method, and then wanted to specify only one of them as a different target for say, POST, that should probably still work. Hmm....

@daylightstudio
Copy link
Contributor Author

daylightstudio commented Aug 3, 2017

I believe that scenario you describe would still work if you add the specific verb after the wildcard. It's when you add the wildcard after the verb that would be the issue if we are wanting the overall ordering of route declaration to determine which route is used. However, I'm feeling that if you specify a specific route over a wildcard, no matter what the order, that should be used (which should be what's happening now).

@lonnieezell
Copy link
Member

Yeah, I agree. It should definitely check the specific verb collection first, and then check the wildcard grouping, and then fail. If that's what you've got, we should be good here, right?

lonnieezell added a commit that referenced this issue Aug 17, 2017
Fix for issue #642 regarding the route_to function and post routes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants