Laravel slug performance eloquent - laravel

I have setup a route like this:
Route::get('/prod/{id}/{title?}', 'Web\GetItemController#getItem')->where('id', '[0-9]+')->name('prod.item');
This is to retrieve a item based on the id the title is only a optional parameter in order to make the url look somewhat nicer.
Then in the controller I fetch the item like this:
class GetItemController extends Controller
{
public function getItem($id, $title = null)
{
$item = new product();
$data = $item->getProdInfo($id);
// Show view with data...
}
}
So I should be able to fetch the item with or without the title parameter.
So a call like this would trigger the route "https://www.x.com/prod/3/sonic-free-games"
But is there any difference in performance using slug like I do above?
/prod/{id}/{title?} vs /prod/{id}

Related

How to include two controller in url in codeigniter 3?

I want to include two controller in a url. Ex. domian.com/category/js/topic/promise. In this, category and topic are controllers and js is argument of category controller, and promise is argument of topic controller.
I have searched, and doesn't found any related example like it. So, How can I achieve this type of url which contains two controller url? I am using codeigniter 3.
/* code of category controller*/
class Category extends MY_Controller{
public function index($category = null){
if($category == null){
// here show all categories using model
}
else{
// show topics of given category
}
}
}
/* code of topic controller */
class Topic extends MY_Controller{
public function index($topic = null){
if($topic == null){
// here show all topics using model of the selected category
}
else{
// show data of selected topic
}
}
}
To use your Topic/index method with your desired url structure, you need to add the following to config/routes.php:
$route['category/(:any)/topic/(:any)'] = "topic/index/$2";
domain.com/category will then show all categories
domain.com/category/index/js will show all topics in a specific category
domain.com/topic will show all topics in all categories
and both domain.com/category/js/topic/promise and domain.com/topic/index/promise will then show a specific topic
If you also need to access the selected category in Topic/index, add it as an argument:
class Topic extends MY_Controller{
public function index($topic = null, $category = null){
if($topic == null){
// here show all topics using model of the selected category
}
else{
// show data of selected topic
}
}
}
And change the route to pass the category from the url onto the method:
$route['category/(:any)/topic/(:any)'] = "topic/index/$2/$1";

Laravel Livewire Save to Collection and Show in Component View

I am using Laravel Livewire to choose an item from a dropdown list (which passes an ID), I then find the Model that ID belongs to and I want to add that Model to a collection. Then each additional time I choose something from the dropdown list I want to update the existing collection with that new Model.
public $workoutExercises;
public function mount()
{
$this->workoutExercises = collect([]);
}
public function submitExercise()
{
$newExercise = Exercise::where('id', $this->exercise)->first();
$this->workoutExercises->push($newExercise);
return;
}
In the component view:
#foreach ($workoutExercises as $workoutExercise)
{{ $workoutExercise->exercise_name }}
#endforeach
When I submit a new exercise it adds it to the collection and shows up in my view as intended. However, when I go to add an ADDITIONAL exercise I get this error..."Attempt to read property "exercise_name" on array".
I don't get it. It's like it adds the first one fine, but resorts to an array instead of a collection for any subsequent submissions?
TIA!
Behind the back, Livewire uses all the things like an array, so when the component first loads your $workoutExercises is a collection, but after the first request it turns into an array. What I usually do is create an array of id's selected and query the data as a computed property.
public array $workoutExerciseIds = [];
public function submitExercise(): void
{
array_push($workoutExerciseIds, $this->exercise);
}
public function getWorkoutExecisesProperty()
{
return Exercise::query()
->whereIn('id', $this->workoutExerciseIds)
->get();
}
Then on my front end:
#foreach ($this->workoutExercises as $workoutExercise)
{{ $workoutExercise->exercise_name }}
#endforeach

Laravel, property not found

Trying to get property from a object in laravel. I have this:
public function index()
{
$firmen = Companies::all();
$allcountcompanies = Companies::count();
$agent = Agent::find($firmen->agent_firma_id);
return view('companies',compact(['firmen'],['allcountcompanies'],['agent']));
}
The Exeption gives me that:
Property [agent_firma_id] does not exist on this collection instance.
But when i put the id eg 1001 it shows corrent entry in db field.
What i0'm doing wrong?
Info:
CompaniesController.php (table: br_firma)
AgentController.php (table: br_firma_agents)
Table "br_firma_agents" contains a foreign_key from table "br_firma".
You are getting id from collection.
$firmens = Companies::all();
it return collection you may be use it useing loop and get one by one data as
for($firmens as $firmen){
$agent = Agent::find($firmen->agent_firma_id);
}
Or you create relation between Company and agent as,
In company model define relation as
public function agents(){
return $this->hasMany(Agent::class);
}
and in agent model define relation as
public function company(){
return $this->belongsTo(Companies::class);
}
and then call it as in controller,
$data = Companies::with('agents')->get();
You are trying to access an agent_firma_id from a collection of companies, you could first use a loop on that collection,or use an index on that collection,
you could try
$firmens = Companies::all();
foreach($firmens as $firmen){
$agent = Agent::find($firmen->agent_firma_id);
}

laravel 5 update in database

I created a row in my 'movies' table called 'slug' where i want to store the slug of the titles of my movies.the problem is i already have 250 movies and i don't want to manually enter the slug to each one of them so i am trying to make a script to automatically update all the slugs.But i failed to do that:
This is my code in FilmController.php:
class FilmController extends Controller {
public function film()
{
$title = DB::table('movies')->select('title');
$slug = str_replace(" ","-",$title);
DB::table('movies')->update(array('slug' => $slug));
}
}
And this is in my routes:
Route::get('update','FilmController#film');
This is the error that pops up when i go to localhost/update:
Object of class Illuminate\Database\Query\Builder could not be converted to string
Can somebody tell me how could i change my code so i can put in my slug field in all the movies the title of the movie with '-' insted of space between the words?
$title is an object containing all titles, and not a string,so str_replace will not work on it
you can try using a loop to update each record according to its title
something like
$titles = DB::table('movies')->select('title','id')->get();
foreach ($titles as $title){
$slug = str_replace(" ","-",$title->title);
DB::table('movies')->where('id',$title->id)->update(array('slug' => $slug));
}
I recomend use a seeder if you want to make a script that update or create default info on your database.
Laravel Database Seeding doc
And title have a collection of titles not a single title.

Laravel eager loading result

I'm having trouble with eager loading in laravel
I have these models:
class Page extends Eloquent {
public function translations() {
return $this->has_many('Pagestl', 'page_id');
}
}
and
class Pagestl extends Eloquent {
public static $table = 'pages_tl';
public function page() {
return $this->belongs_to('Page', 'id');
}
}
I want a specific page with its translation data of a specific language.
I retrieve the data like this:
$page_data = Page::with(array('translations' => function($query) {
$query->where('lang_id', '=', 'nl')->first();
}))->find($id);
De result is ok-ish. I get all the page data and the translation of 1 language, dutch (nl). But in order to get a field from the language data I have to this:
$page_data->translations[0]->attributes['content_or_whatever'];
..which i find ugly. I feel i should only have to do something like:
$page_data->translations->content;
..but that gives me an error (Trying to get property of non-object).
Am I missing something or is this just the way it is?
I don't find it necessary to do eager-loading here.
Both ways of doing it will result in 2 queries: select the Page with the given id and then find its first translation.
So, I would do:
$page = Page::find($id);
and then
$page_data = Pagestl::where_page_id_and_lang_id($page->id, 'nl')->first();
Then, assuming the content field exists in pages_tl table, we'll get it by doing:
echo $page_data->content;
Finally, your code looks alright; you don't have to have the second parameter when defining the relationships unless they are different from what Laravel expects.
I'll let you find where the problem is with your code (I couldn't figure out from the information given - could be something to do with strings.php)

Resources