Tray2 wrote a reply+100 XP
2d ago
Tray2 wrote a reply+100 XP
3w ago
Tray2 wrote a reply+100 XP
3w ago
After making the obvious backup, you can try running
php artisan schema:dump
It should create a sql dump of you current schema. Then any changes to the database after that can be done with regular migrations.
https://laravel.com/docs/13.x/migrations#squashing-migrations
Tray2 wrote a reply+100 XP
1mo ago
Tray2 wrote a reply+100 XP
2mos ago
Tray2 wrote a reply+100 XP
2mos ago
Sounds to me like you didn't run this properly in the UAT environment.
You didn't specify what the failure was, or any error messages, but it should have failed in dev, and test as well.
What I would do, is either manually roll back the changes made by the first migration, or manually deploy the changes that failed.
Tray2 wrote a reply+100 XP
2mos ago
Tray2 was awarded Best Answer+1000 XP
2mos ago
So I would probably go with this kind of database model.
treasure_hunts
- id
- title
quests
- id
- title
quest_trasure_hunt
- treasure_hunt_id
- quest_id
challanges
- id
- description
challange_quest
- challange_id
- quest_id
riddles
- id
- question
- correct_answer_id
answers
- id
- answer
- riddle_id
riddle_user
- riddle_id
- user_id
- answer_id
quest_user
- quest_id
- user_is
Then progress is tracked through the riddle_user table.
Tray2 wrote a reply+100 XP
2mos ago
Tray2 was awarded Best Answer+1000 XP
2mos ago
Apparently it is a reserved word in livewire,
In Livewire 3, naming a method upload in your component is a "gotcha" that causes issues because "upload" is a reserved word used internally by Livewire for handling file uploads. Laravel Livewire Laravel Livewire Using upload as a method name conflicts with Livewire's JavaScript-to-server communication, preventing your component from properly storing files or receiving them as null. The Core Issue Reserved Method/Property: You cannot use upload as a method or property name in your Livewire component class. Why it fails: When a file is selected, Livewire's JS makes a request to a temporary "signed" URL. If you have a method named upload, it clashes with this process. Common Error: The wire:submit or wire:click does not trigger the method, or the file input behaves unexpectedly. Laracasts Laracasts +4 How to Fix It Rename your upload() method to something else, such as save(), submit(), or store().
Tray2 wrote a reply+100 XP
2mos ago
Apparently it is a reserved word in livewire,
In Livewire 3, naming a method upload in your component is a "gotcha" that causes issues because "upload" is a reserved word used internally by Livewire for handling file uploads. Laravel Livewire Laravel Livewire Using upload as a method name conflicts with Livewire's JavaScript-to-server communication, preventing your component from properly storing files or receiving them as null. The Core Issue Reserved Method/Property: You cannot use upload as a method or property name in your Livewire component class. Why it fails: When a file is selected, Livewire's JS makes a request to a temporary "signed" URL. If you have a method named upload, it clashes with this process. Common Error: The wire:submit or wire:click does not trigger the method, or the file input behaves unexpectedly. Laracasts Laracasts +4 How to Fix It Rename your upload() method to something else, such as save(), submit(), or store().
Tray2 wrote a reply+100 XP
2mos ago
I would suggest reading the upgrade guide, it will likely have that issue covered.
Without more code it's hard to say, but there was a change made between version 2 and 3, regarding how you set the model, in version 2 you could do the whole form, but in version 3 you need to set the model on each input.
Tray2 wrote a reply+100 XP
2mos ago
Tray2 wrote a comment+100 XP
2mos ago
I would probably take this a step further, and bring it down to a single query. Since this is some kind of index page, and those are more or less read only, I would create a view in the database, and use that to fetch the orders and the related tables.
Excuse my old school way of writing JOINS in SQL.
This is just an example not an exact rendition of the table and fields used in the video
CREATE VIEW order_index_views AS
SELECT o.id, o.placed_at, oi.product_id, p.name, u.name, u.email
FROM orders o,
order_items oi,
products p,
users u
WHERE o.id = oi.order_id
AND oi.product_id = p.id
AND o.user_id = u.id;
Then I would create a Model for the view called OrderIndexView
And in the controller do
$orderItems = OrderIndexView::orderBy('placed_at')->paginate(50);
This approach will give me a single query, and it will prevent the loading of fields you don't use, and that solves the N+1 and saves memory.
The only issue with this approach, is that you can't really use the nice syntax of the Schema Builder, you need to use a DB:statement to create and drop the view.
If you want more information about how to create and use views in your database, you can check this post out.
https://tray2.se/posts/use-a-view-instead-of-a-complex-eloquent-query-in-your-laravel-application
Tray2 wrote a reply+100 XP
2mos ago
Tray2 wrote a reply+100 XP
2mos ago
Tray2 wrote a comment+100 XP
2mos ago
@terdoo-mzer Simple, anything between the {} is treated like a wildcard.
That means the /ideas/{idea} catches /ideas/create, so it tries to look from a idea with the id of create.
Tray2 was awarded Best Answer+1000 XP
2mos ago
Check out the following posts, they will give you some ideas.
https://tray2.se/posts/database-design
https://tray2.se/posts/database-design-part-2
https://tray2.se/posts/properly-formed-foreign-keys-are-your-best-friends
https://tray2.se/posts/use-a-view-instead-of-a-complex-eloquent-query-in-your-laravel-application
https://tray2.se/posts/using-table-triggers-to-log-changes-in-your-database-tables
Tray2 wrote a reply+100 XP
2mos ago
Check out the following posts, they will give you some ideas.
https://tray2.se/posts/database-design
https://tray2.se/posts/database-design-part-2
https://tray2.se/posts/properly-formed-foreign-keys-are-your-best-friends
https://tray2.se/posts/use-a-view-instead-of-a-complex-eloquent-query-in-your-laravel-application
https://tray2.se/posts/using-table-triggers-to-log-changes-in-your-database-tables
Tray2 wrote a reply+100 XP
2mos ago
Tray2 wrote a reply+100 XP
2mos ago
This is what I do.
- Write code to a make a feature work.
- Refactor/ clean up the code of said feature.
- Start with the next feature and repeat.
If you push on and finish the product, it is likely that you never clean up the code.
So I'd say C. clean up some code, write a feature, clean up some more code until you are done. Make small improvements of the code in iterations, don't try to clean it up all at once, it will likely be overwhelming.
Tray2 wrote a reply+100 XP
2mos ago
Yes, it will likely slow down the import.
You should only have as many indexes as you need, and as few as you can get away with.
Quote from Aaron Francis.
Think of an index as a alphabetically sorted box of cards, and the box is then divided into section A - Z. So every time you need to insert something into the index, you need to first find the section, and then the exact place for it within the section. Now imagine doing that 28 times for each card.
If you are then using MySQL or MariaDB then each time you insert something and the index is refreshed, the table is locked, so you can't insert into it until all indexes are up to date. This will be fairly fast per index, but 28 is a lot, and the indexes will likely cause deadlocks between each other.
Indexes should basically only be used on column that you use in WHERE, ORDER BY, and foreign keys.
Tray2 wrote a reply+100 XP
2mos ago
Tray2 wrote a reply+100 XP
2mos ago
Tray2 wrote a reply+100 XP
2mos ago
So I would probably go with this kind of database model.
treasure_hunts
- id
- title
quests
- id
- title
quest_trasure_hunt
- treasure_hunt_id
- quest_id
challanges
- id
- description
challange_quest
- challange_id
- quest_id
riddles
- id
- question
- correct_answer_id
answers
- id
- answer
- riddle_id
riddle_user
- riddle_id
- user_id
- answer_id
quest_user
- quest_id
- user_is
Then progress is tracked through the riddle_user table.
Tray2 wrote a comment+100 XP
2mos ago
@JakovljevicFilip You are correct, they are both viable options. I however, am more in the camp of letting the database handle any kind of filtering, sorting, counting, and such, much rather than letting php handle that.
Tray2 wrote a comment+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
Tray2 was awarded Best Answer+1000 XP
3mos ago
It fails because of this line $user = $users->find(1);
When you refresh the database, you don't reset the internal sequence of the id. That means that the first time you run it, it creates id 1, and 2, the next time it creates id 3 and 4, and so on.
Truncating the table resets the internal sequence, thus giving you id 1 and 2 every time you run the test.
So changing the line to
$user = $user->first();
Or to
$user = $user->find($users[0]->id);
Should solve your issue.
Tray2 wrote a comment+100 XP
3mos ago
One important thing when creating routes like that, is the order.
Route::get('/ideas/create', [IdeaController::class, 'index']);
Must be defined before
Route::get('/ideas/{idea}', [IdeaController::class, 'show']);
Or you will scratch your head as to why you get a 404 when trying to navigate to the create Idea route.
Tray2 wrote a reply+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
If you are using MySQL/MariaDB you don't need to add it manually like that, it's added automatically.
I just created this migration.
public function up(): void
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
And when I run show index from books
I get the following
{
"Table": "books",
"Non_unique": 0,
"Key_name": "PRIMARY",
"Seq_in_index": 1,
"Column_name": "id",
"Collation": "A",
"Cardinality": 0,
"Sub_part": null,
"Packed": null,
"Null": "",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": "",
"Visible": "YES",
"Expression": null
}
{
"Table": "books",
"Non_unique": 1,
"Key_name": "books_user_id_foreign",
"Seq_in_index": 1,
"Column_name": "user_id",
"Collation": "A",
"Cardinality": 0,
"Sub_part": null,
"Packed": null,
"Null": "",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": "",
"Visible": "YES",
"Expression": null
}
If I add the index name like you did
public function up(): void
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained(indexName: 'FK_BOOK_USER')->onDelete('cascade');
$table->timestamps();
});
}
Then I get
{
"Table": "books",
"Non_unique": 1,
"Key_name": "FK_BOOK_USER",
"Seq_in_index": 1,
"Column_name": "user_id",
"Collation": "A",
"Cardinality": 0,
"Sub_part": null,
"Packed": null,
"Null": "",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": "",
"Visible": "YES",
"Expression": null
}
Tray2 wrote a reply+100 XP
3mos ago
Tray2 wrote a reply+100 XP
3mos ago
Since the code you have shown only passes those to the view, then it makes sense to use a view composer. If you just to use them for some logic in other methods in the controller, then I would set them in a constructor method.
class PagamController extends Controller
{
protected int $minYear;
protected int $maxYear;
public function __construct()
{
$this->minYear = Pagam::whereNotNull('etoscreated')->min("etoscreated");
$this->maxYear = Pagam::whereNotNull('etoscreated')->max("etoscreated");
}
Tray2 wrote a reply+100 XP
3mos ago
You can use a view composer to share that information
https://laravel.com/docs/12.x/views#view-composers
I would also suggest that you code in English, you will get a lot of help from the framework.
Tray2 wrote a reply+100 XP
4mos ago
Tray2 wrote a reply+100 XP
4mos ago
Tray2 wrote a reply+100 XP
4mos ago
Try
public function users_search_returns_results_for_existing_data(array $payload)
{
$users = User::factory()->createMany($payload);
dd($users);
$user = $users->find($users[0]->id);
$response = $this
->withHeader("Accept", 'application/json')
->actingAs($user)
->getJson(route('authors.index', ['search' => 'b']));
$response->assertStatus(200);
$response->assertJsonCount(1, 'data');
}
To make sure you have a user, and then you can try,
$user = User::find($users[0]->id);
Tray2 wrote a reply+100 XP
4mos ago
Tray2 wrote a reply+100 XP
4mos ago
It fails because of this line $user = $users->find(1);
When you refresh the database, you don't reset the internal sequence of the id. That means that the first time you run it, it creates id 1, and 2, the next time it creates id 3 and 4, and so on.
Truncating the table resets the internal sequence, thus giving you id 1 and 2 every time you run the test.
So changing the line to
$user = $user->first();
Or to
$user = $user->find($users[0]->id);
Should solve your issue.