Laravel 5.3 Route model binding with multiple parameters - laravel-routing

Is it possible to have route model binding using multiple parameters? For example
Web Routes:
Route::get('{color}/{slug}','Products#page');
So url www.mysite.com/blue/shoe will be binded to shoe Model, which has color blue.

First of all, it would feel more natural to have a route like the following:
Route::get('{product}/{color}', 'Products#page');
and to resolve product by route binding, and just use the color parameter in the controller method directly, to fetch a list of blue shoes for example.
But let's assume that for some reason it's a requirement. I'd make your route a bit more explicit, to start with:
Route::get('{color}/{product}', 'Products#page');
Then, in the boot method of RouteServiceProvider.php, I would add something like this:
Route::bind('product', function ($slug, $route) {
$color = $route->parameter('color');
return Product::where([
'slug' => $slug,
'color' => $color,
])->first() ?? abort(404);
});
first here is important, because when resolving route models like that you effectively want to return a single model.
That's why I think it doesn't make much sense, since what you want is probably a list of products of a specific color, not just a single one.
Anyways, I ended up on this question while looking for a way to achieve what I demonstrated above, so hopefully it will help someone else.

Do not forget to declare the parameter types:
Route::delete('safedetail/{safeId}/{slug}', [
'as' => 'safedetail.delete',
'uses' => 'SafeDetailController#destroy',
])->where([
'safeId' => '[0-9]+',
'slug' => '[a-z]+',
]);

Try changing your controller to this:
class Pages extends Controller{
public function single($lang, App\Page $page){
dd($page);
}
}
You must add the Page Model.

Related

Cypress Get Attribute value and store in Variable

I want to get the Attribute value and store in a variable how we can achieve this in cypress
In my case I want to get the complete class value and store it in variable.
This code just give me the attribute class value but how I can store the fetch value in variable
cy.get('div[class*="ui-growl-item-container ui-state-highlight ui-corner-all ui-shadow ui-growl-message"]').invoke('attr', 'class')
I was trying to compare the style of one element with another to make sure they were equal. Here's the code that seems to work for me.
cy.get('.searchable-group-selector-card-image')
.eq(4)
.invoke('attr', 'style')
.then(($style1) => {
const style1 = $style1
})
A good way to solve this kind of scenario is to use the alias mechanism. One could leverage this functionality to enqueue multiple elements and then check all of them together by chaining the results. I've recently come to a case in an SPA where the assertion had to happen between elements that were spread across different angular routes (call them different pages).
In your use case, this would like:
cy.get('.searchable-group-selector-card-image')
.eq(4)
.invoke('attr', 'style')
.as('style_1')
cy.get('.another-element')
.invoke('attr', 'style')
.as('style_2')
// later on for example you could do
cy.get('#style_1').then(style_1 => {
cy.get('#style_2').then(style_2 => {
// Both values are available and any kind of assertion can be performed
expect(style_1).to.include(style_2)
});
});
This is described in Variables and Aliases section of the Cypress Documentation.
Here is how I got the value of for attribute in a label tag which had text "Eat" inside.
cy.contains('Eat').then(($label) => {
const id = $label.attr('for');
}
Most important thing is to get the selector right, so it exactly finds the value you are looking for. In this case you already found it. By using then() gives you the ability to store it in a variable.
cy.get('div[class*="ui-growl-item-container ui-state-highlight ui-corner-all ui-shadow ui-growl-message"]').invoke('attr', 'class')
.then($growl-message => {
const message = $growl-message.text()
//do the checks with the variable message. For example:
cy.contains(message)
})
Note that the scope of the variable is within the curly brackets. Thus using the variable has to be within those curly brackets.

How to define route in phalcon

I have controller named GlossaryController with 2 actions indexAction and anotherAction in view i have a directory glossary and index.volt file
i want to define a route with parameters for example
http://localhost/project/glossary/another/params it should redirect me to indexAction with parameters
In your routes.php file in app/config folder add this line:
$router->add("/glossary/another/{param1}/?{param2}", array(
"controller" => "Glossary",
"action" => "another",
));
And your anotherAction method will be like:
public function anotherAction($param1, $param2 = 0) {
//some code
}
This way first param must be sent, second one is optional, you can add this way as much params as you like.
See official docs for various ways of routing:
https://olddocs.phalconphp.com/en/3.0.3/reference/routing.html

Laravel Queries / Controller Edits

So I am pretty new to Laravel, and I have spent the whole day fishing through various documentations but I am stuck on the way queries work within the actual application. Right now, I am trying to get some data in my database to display, and I looked at the query builder so that's where I am right now. I am also using a CRUD based admin panel for entry in the database. And since it is CRUD based, it has created the model and the controller already, so I am wondering if I need to edit any of those files to get this to work. Here is what the public function index() has right now (Using Laraadmin):
$module = Module::get('Events');
if(Module::hasAccess($module->id)) {
return View('la.events.index', [
'show_actions' => $this->show_action,
'listing_cols' => $this->listing_cols,
'module' => $module
]);
} else {
return redirect(config('laraadmin.adminRoute')."/");
}`
Obviously, I am trying to display some data from this Events table into my blade view. From what I was reading, I understood (or I thought) that it would be something similar to this:
foreach ($module as $module) {
echo $module->id;
}
But, I keep getting an error that whatever variable I pass in the loop is undefined, although I thought it was in the controller. Right now my model is just returning the view as well. Any help with this is greatly appreciated, or even just an explanation of the relationships with queries in Laravel. Thanks!
A few things to check when this happens:
Change module to a known array. This tests if your data array is set up correctly:
'module' => [ '1', '2', '3' ], // previously $module
Within the blade, now write a simple loop, such as:
#foreach ($module as $m)
{{ $m }}
#endforeach
If this version does work, then you know you have something up with your $module variable.
If the above still doesn't work, try to simplify your view request (temporarily):
view('foo', ['a' => 555]);
Then in foo.blade.php, simply have:
hello {{ a }}
EDIT
If all this seems to be correct, then the data being fetched is probably wrong (so its not a view issue). Try $module = Module::all();
It seems like you are returning a view that doesn't exist. If what you have now was correct, it would be looking for resources/views/la/events/index.blade.php Try replacing that return view line with this:
return view('events', [ ... rest of your variables ]);
And just a side note, on your foreach statement, it's probably best to use two separate variable names... so something like:
foreach ($module as $element) { ...

Pass values to route

I have a list of items. When the user clicks on an item, the user will be taken to item details page.
I want to pass an object containing item details(like item's image URL) to the route. However, I don't want to expose it in the routes url.
If there were a way to do something like <a route-href="route: details; settings.bind({url: item.url})">${item.name}</a> that would be gold.
I have seen properties can be passed to a route if defined in the route configuration. However, I don't know how to change that from the template. Another way could be is to define a singleton and store the values there and inject the object to the destination route.
Is there a way to pass values to routes from view (like angular ui-routers param object)?
Okay so I figured out a way to achieve something closer to what I wanted:
Objective: Pass data to route without exposing them in the location bar.
Let's say, we have a list of users and we want to pass the username to the user's profile page without defining it as a query parameter.
In the view-model, first inject Router and then add data to the destination router:
goToUser(username) {
let userprofile = this.router.routes.find(x => x.name === 'userprofile');
userprofile.name = username;
this.router.navigateToRoute('userprofile');
}
Now when the route changes to userprofile, you can access the route settings as the second parameter of activate method:
activate(params, routeData) {
console.log(routeData.name); //user name
}
For those #Sayem's answer didn't worked, you can put any additional data (even objects) into setting property like this:
let editEmployeeRoute = this.router.routes.find(x => x.name === 'employees/edit');
editEmployeeRoute.settings.editObject = employeeToEdit;
this.router.navigateToRoute('employees/edit', {id: employeeToEdit.id});
So editObject will be delivered on the other side:
activate(params, routeConfig, navigationInstruction) {
console.log(params, routeConfig, navigationInstruction);
this.editId = params.id;
this.editObject = routeConfig.settings.editObject;
}
hopes this helps others encountering same problem as me. TG.

ZF2, how to create form view helper?

I want to change the way ZF2 shows the form elements. I think I have to create my own view helper but I don't know how.
I Googled for it but didn't find any useful resource.
See the SourceCode of existing Zend\Form\View\Helper*
Basically you extend those and overwrite the required functions of stuff you want to modify.
After that you'll need to register your very own view helper. This is easily done within Module.php's getViewHelperConfig()
public function getViewHelperConfig()
{
return array(
'invokables' => array(
'customViewHelperCallName' => 'Namespace\Form\View\Helper\Classname'
)
);
}