How To Access A Column In M-M Relationship Table In Laravel
I made a many-to-many relationship in laravel, where users can make announcements on an event.
The problem is that I want to retrieve the announcement message from the database using the relationship.
Here is my code:
Database Migration:
Schema::create('announcements', function (Blueprint $table) {
$table->id();
$table->text("message");
$table->foreignId('user_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate();
$table->foreignId('event_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate();
$table->timestamps();
});
Event Model:
public function announcements() {
return $this->belongsToMany(User::class, 'announcements');
}
User Model:
public function announcements() {
return $this->belongsToMany(Event::class, 'announcements');
}
Events Controller:
public function getEventAnnouncements($id) {
$event = Event::find($id);
$ann = [];
$event->announcements->each(function ($a) use ($ann) {
// echo $a;
// $ann += $a->message;
});
return $ann;
}
What Should I Write In The Controller To Get The Content Of messages
Column ?
2 answers
-
answered 2022-05-06 01:20
Moustafa Mahmoud
You could access the message attribute by using The pivot keyword...
$event->announcements->pivot->message ;
So by this way you could access it And i have a small advice for you change the name of your pivot table to user_event to be more clear
-
answered 2022-05-06 02:38
Kareem Salem
I Found The Solution!
First I was supposed to add a pivot in the Models
Event Model:
public function announcements() { return $this->belongsToMany(User::class, 'announcements')->withPivot('message'); }
User Model:
public function announcements() { return $this->belongsToMany(Event::class, 'announcements')->withPivot('message'); }
And Finally Loop Through The Results To Get Messages.
EventsController:
$ann = []; foreach ($event->announcements as $a) { $ann[] = [ "name" => $a->name, "announcement" => $a->pivot->message, "created_at" => $a->pivot->created_at, ]; }
It Worked Fine!
do you know?
how many words do you know
See also questions close to this topic
-
How to upload a video using ACF in WordPress?
I am still at learning phase in WordPress. I cannot figure out in ACF which field type should I choose to upload a video file and which code should I write to show it at the front-end. Please look into the below code. I am using the_field('') but it isn't working. Can anyone help
<video width="954" height="535" controls class="tm-mb-40"> <source src="video/wheat-field.mp4" type="video/mp4"> Your browser does not support the video tag. </video>
-
delete a table form a database using laravel command
i need to delete a database table using laravel artisan command . not like this command php artisan migrate:rollback --step=5
i need to create like this route or controller code .
Route::get('/clear/database', function () {
Artisan::call('cache:clear'); return redirect('/');
});
. i also try public function dd()
{ Schema::drop('table_name'); }
but it not working . gives me error like this SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table
table_name
)no foreign key for the table . what should i do ?
thanks in advance!
-
Creating Sticky Navbar with Drop Down Menu HTML
I am creating a HTML web page which contains a sticky navbar with drop down menu. However, when I created one, the dropdown menu does not works in the sticky navbar and so goes vise versa. below is the screenshot of both the result of the two codes.
*image with dropdown menu but without sticky navbar
*image with sticky navbar but without dropdown menu
below is the code for "image with dropdown menu but without sticky navbar"
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font- awesome/4.7.0/css/font-awesome.min.css"> <style> body {margin:0;font-family:Arial} .topnav { overflow: hidden; background-color: #333; } .topnav a { list-style-type: none; float: left; display: block; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; position: sticky; } .active { background-color: #04AA6D; color: white; } .topnav .icon { display: none; } .dropdown { float: left; overflow: hidden; } .dropdown .dropbtn { font-size: 17px; border: none; outline: none; color: white; padding: 14px 16px; background-color: inherit; font-family: inherit; margin: 0; } .dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } .topnav a:hover, .dropdown:hover .dropbtn { background-color: #555; color: white; } .dropdown-content a:hover { background-color: #ddd; color: black; } .dropdown:hover .dropdown-content { display: block; } @media screen and (max-width: 600px) { .topnav a:not(:first-child), .dropdown .dropbtn { display: none; } .topnav a.icon { float: right; display: block; } } @media screen and (max-width: 600px) { .topnav.responsive {position: relative;} .topnav.responsive .icon { position: absolute; right: 0; top: 0; } .topnav.responsive a { float: none; display: block; text-align: left; } .topnav.responsive .dropdown {float: none;} .topnav.responsive .dropdown-content {position: relative;} .topnav.responsive .dropdown .dropbtn { display: block; width: 100%; text-align: left; } } </style> </head> <body> <div class="header"> <h2>Scroll Down</h2> <p>Scroll down to see the sticky effect.</p> </div> <div class="topnav" id="myTopnav"> <a href="#home" class="active">Home</a> <a href="#news">News</a> <a href="#contact">Contact</a> <div class="dropdown"> <button class="dropbtn">Dropdown <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <a href="#about">About</a> <a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">☰</a> </div> <div style="padding-left:16px"> <h2>Responsive Topnav with Dropdown</h2> <p>Resize the browser window to see how it works.</p> <p>Hover over the dropdown button to open the dropdown menu.</p> </div> <h3>Sticky Navigation Bar Example</h3> <p>The navbar will <strong>stick</strong> to the top when you reach its scroll position.</p> <p><strong>Note:</strong> Internet Explorer do not support sticky positioning and Safari requires a -webkit- prefix.</p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <script> function myFunction() { var x = document.getElementById("myTopnav"); if (x.className === "topnav") { x.className += " responsive"; } else { x.className = "topnav"; } } </script> </body> </html>
below is the code for "image with sticky navbar but without dropdown menu"
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font- awesome/4.7.0/css/font-awesome.min.css"> <style> body { font-size: 20px; } body {margin:0;} ul { list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #333; position: -webkit-sticky; /* Safari */ position: sticky; top: 0; } li { float: left; } li a { display: block; color: white; text-align: center; padding: 16px 20px; text-decoration: none; } li a:hover { background-color: #111; } /*======================================================================*/ body { background-color:white; } ul { list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #38444d; } li { float: left; } li a, .dropbtn { display: inline-block; color: white; text-align: center; padding: 14px 16px; text-decoration: none; } li a:hover, .dropdown:hover .dropbtn { background-color: red; } li.dropdown { display: inline-block; } .dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .dropdown-content a { color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } .dropdown-content a:hover {background-color: #f1f1f1;} .dropdown:hover .dropdown-content { display: block; } footer { text-align: center; padding: 3px; background-color: DarkSalmon; color: white; } </style> </head> <body> <div class="header"> <h2>Scroll Down</h2> <p>Scroll down to see the sticky effect.</p> </div> <ul> <li><a href="#home">Home</a></li> <li><a href="#news">News</a></li> <li class="dropdown"> <a href="javascript:void(1)" class="dropbtn">Dropdown</a> <div class="dropdown-content"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </li> </ul> <h3>Sticky Navigation Bar Example</h3> <p>The navbar will <strong>stick</strong> to the top when you reach its scroll position.</p> <p><strong>Note:</strong> Internet Explorer do not support sticky positioning and Safari requires a -webkit- prefix.</p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <p>Some text to enable scrolling. </p> <footer> <p>Author: Hege Refsnes<br> <a href="mailto:hege@example.com">hege@example.com</a></p> </footer> </body> </html>
Please i need some help with this as i am new to html and css.
-
Why does this Sql query shows the possible changes but does not implement it?
So, I want to change the prefix of my tables and the following command shows the possible changes that will take place which seems alright but does not seem to implement it.
SELECT Concat('RENAME TABLE ', TABLE_NAME, ' TO fan_', SUBSTRING_INDEX(TABLE_NAME, 'pc_',-1), ';') FROM information_schema.tables WHERE table_name like 'pc_%' and table_schema='testdbhere'
Moreover, this isn't a writing privilege issue as changing the tables name individually works perfectly from the same user.
-
how to get weeklytotal and yesterday record in mysql in one table
Hi Everyone i am trying to implement query to get weekly and yesterday data in same table, dummy output i have shared below, if yesterday not exist as per employee_id it should we showing 0 also as per my table week start from monday and end at sunday.please help me out how to query this get weekly_total and yesterday record and one table.
Table name-dailydata-
Sample data
employee_id date total 20 2022-04-25 10 20 2022-04-26 20 20 2022-04-27 20 20 2022-04-28 10 20 2022-04-29 20 20 2022-04-30 30 20 2022-04-31 40 20 2022-05-01 50 40 2022-04-26 20 expected output
employee_id weekly_total yesterday_record 20 200 40 40 20 0 mysql query to get weekly data
select employee_id,sum(total) as week_total from dailydata where date between '2022-04-25' and '2022-05-01'
-
Join to another table only matching specific records
I have a table of ports:
drop table if exists ports; create table ports(id int, name char(20)); insert into ports (id, name ) values (1, 'Port hedland'), (2, 'Kwinana');
And a table of tariffs connected to those ports:
drop table if exists tariffs; create table tariffs(id int, portId int, price decimal(12,2), expiry bigint(11)); insert into tariffs (id, portId, price, expiry ) values (1, 2, 11.00, 1648408400), (2, 2, 12.00, 1648508400), (3, 2, 13.00, 1648594800), (4, 2, 14.00, 1651273200), (5, 2, 15.00, 2250000000 ); insert into tariffs (id, portId, price, expiry ) values (1, 1, 21.00, 1648408400), (2, 1, 22.00, 1648508400), (3, 1, 23.00, 1648594800), (4, 1, 24.00, 1651273200), (5, 1, 25.00, 2250000000 );
Each tariff has an expiry.
I can easily make a query to figure out the right tariff for as specific date for each port. For example at timestamp
1648594700
the right tariff is:SELECT * FROM tariffs WHERE 1648594700 < expiry AND portId = 2 ORDER BY expiry LIMIT 1
Result:
id portId price expiry 3 2 13.00 1648594800
However, in my application I want to be able to pull in the right tariff starting from the
ports
record.For one record, I can do this:
SELECT * FROM ports LEFT JOIN tariffs on tariffs.portId = ports.id WHERE 1648594700 < tariffs.expiry AND ports.id = 2 LIMIT 1
Result:
id name id portId price expiry 2 Kwinana 3 2 13.00 1648594800
This feels a little 'dirty', especially because I am doing a lookup on a record, and then forcing only one result using LIMIT. But, OK.
What I cannot do, and can't work out how to do, is a query that will return a list of ports, and each port having a
price
field that matches the constraint above (that is, the record with the highestexpiry
compared to1648594700
for each port).This obviously won't work:
SELECT * FROM ports left join tariffs on tariffs.portId = ports.id where 1648594700 < tariffs.expiry
Since the result of the query, testing with timestamp
1648594700
, would be:id name id portId price expiry 2 Kwinana 3 2 13.00 1648594800 2 Kwinana 4 2 14.00 1651273200 2 Kwinana 5 2 15.00 2250000000 1 Port he 3 1 23.00 1648594800 1 Port he 4 1 24.00 1651273200 1 Port he 5 1 25.00 2250000000
Instead, the result for all ports (before further filtering) should be:
id name id portId price expiry 2 Kwinana 3 2 13.00 1648594800 1 Port he 3 1 23.00 1648594800
Is there a clean, non-hacky way to have such a result? As an added constraint, is this possible for this to be done in ONE query, without temp tables etc.?
-
Foreach for Categories
i have this data, I want to loop with categories for each question. Right now all I can do is loop by displaying sequentially for each question (as in the image).what I want to do is loop and group them based on categories_id , if the categories_id changes it will be given a new line.
// 20220507095412 // http://127.0.0.1:8000/user/exams [ { "id": 16, "ujians_id": 11, "questions_id": 3, "mulai": null, "berakhir": null, "durasi": 60, "isAnswer": 0, "created_at": "2022-05-07T02:53:56.000000Z", "updated_at": "2022-05-07T02:53:56.000000Z", "questions": { "id": 3, "title": "2", "question": "<p>Sarana yang sangat masih dalam menyebabkan oposisi dunia yang sering berdampak pada intervensi asing terhadap Indonesia pada era globalisasi sekarang ini adalah...</p>", "img": null, "categories_id": 1, "created_at": "2022-05-07T02:11:41.000000Z", "updated_at": "2022-05-07T02:11:41.000000Z" } }, { "id": 17, "ujians_id": 11, "questions_id": 1, "mulai": null, "berakhir": null, "durasi": 60, "isAnswer": 0, "created_at": "2022-05-07T02:53:56.000000Z", "updated_at": "2022-05-07T02:53:56.000000Z", "questions": { "id": 1, "title": "13", "question": "<p>Wahidin soedirohoesodo memilik peran penting dalam pergerakan kemerdekaan. Antara lain…22234232</p>", "img": null, "categories_id": 1, "created_at": "2022-05-02T10:39:13.000000Z", "updated_at": "2022-05-03T13:28:24.000000Z" } } ]
@php $no=1 @endphp @foreach($dataUjian as $row) @if($row->isAnswer == 0) <button class="btn btn-primary btn-sm" onclick="getUjian({{$row->questions_id}}, {{$row->id}},{{$row->ujians->users_id}})" >{{$no++}}</button> @else <button class="btn btn-danger btn-sm" disabled>{{$no++}}</button> @endif @endforeach
-
Unit testing with get request
I am trying to create a unit test for one of my api.
In the frontend, I send it this way...
params = { participants: JSON.stringify(participants), section: JSON.stringify(section), }; axios.get('/api/list', params)
while in the controller, it receives the params this way...
public function list(Request $request) { $participants = json_decode($request->participants); $section = json_decode($request->section); }
Now, I tried making a unit test out of this. by doing...
$params = [ 'participants' => ['id', 'name', 'rating'], 'section' => ['id', 'code'], ]; $this->get('/api/list'.http_build_query($params))->assertStatus(200) // $this->json('/api/list', $params)->assertStatus(200) // -> also tried this one // $this->getJson('/api/list', $params)->assertStatus(200) // -> also tried this one // $this->call('GET', '/api/list', $params)->assertStatus(200) // -> also tried this one
But none of them works, it always says
TypeError: json_decode(): Argument #1 ($json) must be of type string, array given
.So, the way I built the url and the params must be all wrong,
so my question here is that, what's the correct way of building the url so that it provides a correct url string format and the controller will json_decode the params?
-
How to create a full text index with PHP attributes and Symfony 6?
I need to create a search input inside my symfony 6.0 project. I'm using PHP 8.1.5
In the old days i used the following syntax with annotations :
/** * @ORM\Table(name="category", indexes={@ORM\Index(columns={"name", "description"}, flags={"fulltext"})}) */ class Category {
But right now i'm not able to find the good way to do it using attributes. I tried the following :
#[ORM\Index(name: 'category_idx', columns: ['name', 'description'])]
but the migration didn't create a full text index.
Could you please tell me how you did it if you already had this situation ?
-
joinColumns in Hibernate for standard relations?
In the following example, there are 3 entities which have relations e.g. @ManyToMany, @OneToMany and @ManyToOne:
Student:
@Entity @Data public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Long id; private String name; @JsonIgnore @ManyToMany(mappedBy = "students") private Set<Subject> subjects = new HashSet<>(); }
Subject:
@Entity @Data public class Subject { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Long id; private String name; @ManyToMany @JoinTable( name = "subject_student", joinColumns = @JoinColumn(name = "subject_id"), inverseJoinColumns = @JoinColumn(name = "student_id") ) Set<Student> students = new HashSet<>(); @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "teacher_id", referencedColumnName = "id") private Teacher teacher; }
Teacher:
@Entity @Data public class Teacher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @JsonIgnore @OneToMany(mappedBy = "teacher") private Set<Subject> subjects; }
1. In the subject entity, I tried to remove
@JoinColumn
and the related entities are connected as the example above:@ManyToMany @JoinTable(name="subject_student") public Set<Student> students = new HashSet<>(); @ManyToOne(cascade = CascadeType.ALL) private Teacher teacher;
So, if we want to use
subject_id
-student_id
pair insubject_student
table and useteacher_id
in subject table as it is created in the example, can I use my simplified notation by removing@JoinColumn
? Because, if there is not a special case, I think it is redundant to verbose notation of relations.2. When I use the second approach, the columns are created as plural e.g.
subjects_id
-students_id
insubject_student
. So, can I prevent this and create them as in the previous example by using my approach? -
How to check authorization before loading Route Model Binding
I ask this question after doing various searches without finding any clarifying information that helps me solve the problem that I am presenting.
I have created a controller with the following command:
php artisan make:controller UserController --api -m User -r -R
Which creates the controller and the FormRequest classes. Inside the controller, let's just focus on the
'update'
method, since that's the one I'm having some trouble with.<?php namespace App\Http\Controllers; use App\Http\Requests\StoreUserRequest; use App\Http\Requests\UpdateUserRequest; use App\Models\User; class UserController extends Controller { /** * Update the specified resource in storage. * * @param \App\Http\Requests\UpdateUserRequest $request * @param \App\Models\User $user * @return \Illuminate\Http\Response */ public function update(UpdateUserRequest $request, User $user) { // } ...
As you can see from the method arguments, this method uses what we call Route Model Binding
After this, I define my route in the routes file
'api.php'
as follows:<?php use App\Http\Controllers\UserController; use Illuminate\Support\Facades\Route; Route::middleware('auth:sanctum')->group(function () { Route::apiResource('user', UserController::class); });
Which registers all the routes and within them the
'update'
route.In the FormRequest class named
'UpdateUserRequest'
, which uses the'update'
method in the previously created controller, I define the'authorize'
method to return false on all checks just for testing. The class would look similar to this:<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule; class UpdateUserRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return false; } ...
Now, the problem that I am presenting, when I access the route:
http://127.0.0.1:8000/api/user/100?
Using Postman, I make a request to that route with the
PUT
method and Laravel returns the following error:{ "message": "No query results for model [App\\Models\\User] 100" }
This is because I don't have a
user
with'id'
100, I only have 2 users in my database for testing purposes.My question is this: Isn't Laravel supposed to return an error on this request? Telling me that the action is not allowed, since in the FormRequest
'UpdateUserRequest'
class, in the'authorize'
method, I always returnfalse
.I think Laravel is loading the middleware
\Illuminate\Routing\Middleware\SubstituteBindings::class
before middleware\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class
.I know that in the
app/Http/Kernel.php
file I can modify the middleware priority, overriding the$middlewarePriority
property, but I've tried it and I don't get the expected result.Because from my perspective, it doesn't make much sense, taking the previous example that a user who doesn't have permissions to update the model
User
tries to access the route and Laravel returns an error saying that the user trying to modify with thatid
exists or not, without first verifying that the user trying to perform the(update)
action has or does not have permissions to perform it. -
Problems in Laravel when logging in
I am uploading my first Laravel application to a hosting, and after creating a user, I get the following error:
I am seeing that the registration of the new user was created successfully scheenshot pryect in host
My project is in the dash_roles test folder, while everything that was in public, I put in the public_html folder.
I clarify that the project is with Laravel 9, I already verified that the same version of PHP with which I made the project is selected on my server. Modify the lines in the index.php file located in public_html.
If you need me to upload something else so you can find where the error is, let me know and I'll upload it.
Thanks!
edit: here a screenshot for my assets un app.blade.php enter image description here