i'm trying to create a simple Quiz App with Laravel and Mysql .
the idea is , i'm stucked on the relattions between questions/options .
first i create a table called "quiz"
ID name
1 Brazil
2 EUA
3 Japan
a table called "questions"
ID quiz_id name
1 1 President ?
2 1 Food?
3 1 Music?
4 1 Maiority?
and a table called "options"
ID question_id name
1 1 lula
2 1 bolsonaro
3 2 rice
4 2 beans
5 3 samba
6 3 rock
7 4 black
8 4 white
like image below , i receive the questions related with quiz . my function on my HomeController looks like this .
public function index(){
$quiz = Quiz::where('id',1)->with('questions')->get();
$array = array('quiz' =>$quiz);
return $array;
}
and my model Quiz have this relationship
public function questions(){
return $this->hasMany('App\quizquestion', 'quiz_id');
}
but i wanna make a relation of questions with options .
i'm thinking that must be another sub object inside questions . like a thirty leve .
Example :
quiz
questions
options.
because i wanna call this on my blade template , actualy i 'm calling this way
<body>
#foreach($quiz as $item)
<h1>{{$item->name}}</h1>
#foreach($item->questions as $quest)
<p>{{$quest->question}}</p>
#endforeach
#endforeach
</body>
that return me :
Brazil
President ?
Food ?
Music ?
Maiority?
I think you are looking for nested relationship query.
I assume you already setup the questions-options relationship. Here is a simplified query:
Quiz::with(['questions', 'questions.options'])->get();
or simpler (credits to #lagbox) :
Quiz::with('questions.options')->get();
Related
I have 2 tables i.e. users and user_managers, with the following structure and data:
users
id
name
employee_number
1
Employee One
ACB1234
2
Employee Two
XYZ1234
3
Employee Three
EFG1234
4
Employee Four
HIJ1234
user_managers
id
user_id
manager_of_user_id
1
1
2
2
2
3
3
4
1
4
5
4
I want a recursive function to get the complete chain of the managers. For example, if query for user_id = 4, I should get the following result:
result
user_id
name
employee_id
comments
1
Employee One
ABC1234
user managed by 4
2
Employee Two
XYZ1234
user managed by 1
3
Employee Three
EFG1234
managd by user 2
5
Employee Five
JKL1234
manager of user 4
The table above is just for the clarification, I am looking for a recursive function to get the above result.
I have tried the below solution but it is working for only 1 level.
public static function getCompleteChain(User $user)
{
$managerUsers = $user->managers;
foreach ($managerUsers as $manager) {
$manager->user = User::where('employee_id', $manager->manager_of_user_id)->first();
self::getCompleteChain($manager->user);
}
return $managerUsers;
}
Thanks in advance.
CONTEXT
I am managing products. This is a shoe store. I would like to offer a view of the other variants.
The database is shaped like this:
For example you can have a leather shoe (id 1), and there is 3 variants of this shoe: a black (id 1), a brown (id 2), and a grey (id 3).
What I try to do is to construct a Laravel relationship to be able, from one variant, to get its siblings. Here is what it looks like in the database according to the example I mentioned.
SHOE
id
====
1
SHOE_VARIANT
id shoeId colorId
===================
1 1 1
2 1 2
3 1 3
...
8 2 5
9 3 2
10 3 4
In this case, if the user is viewing the black variant (id 1), I whish I could show him the 2 others variants (brown, id 2, and grey, id 3).
QUESTION
How can I construct a Laravel relationship in order to retrieve siblings from a parent id, and make sure the current record itself is not included?
EXPERIMENTS
I already tried to construct a relationship like below, but the current record itself is included and I can't figure out how to exclude the record itself because I did not find how to get the current id of the record.
// app/ShoeVariant.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ShoeVariant extends Model {
public function siblings() {
return $this->hasMany("App\ShoeVariant", "shoeId", "shoeId");
}
}
This means:
For the current shoe variant, get the shoe variants that matches knowing that you should match the foreign column named "shoeId" and the local column named "shoeId"
So if 2 shoe variants share the same column "shoeId", this works. Stuck in excluding the current record from these results.
This should do what you want:
public function siblings() {
return $this->hasMany('App\ShoeVariant', 'shoeId', 'shoeId')
->where('id', '!=', $this->id);
}
Just filter out the current variant by id and get all the others.
Alternatively, you can just make a new property:
public function getVariantsAttribute() {
return $this->siblings->reject(function($elem) {
return $elem->id == $this->id;
});
}
And then use it in code like:
$variants = $model->variants; // all except this one
My database schema is
links:
id status user_id url
1 1 1 something
2 1 1 something
3 1 1 something
links_type:
id link_id links_type
1 1 external
2 1 external
3 1 internal
4 1 external
5 2 internal
6 2 external
7 2 internal
8 2 external
i want to take data of all links which status is 1 and user_id is 1
and count external and internal links and which external count is >2.
by using laravel 5.2 eloquent.
result should be like this from data given
id status user_id url external_links internal_links
1 1 1 something 3 1
Just define this relationship in Link Model
public function link_type()
{
return $this->hasMany('App\linkType');
}
and use this query
Link::where('status','=','1')->where('user_id','=','1')->has('link_type','>', '2')->with('link_type')->get();
If you already have the right migrations with fk's and Models following code should be working:
$links = Link::where('status','=','1')->where('user_id','=','1')
->whereHas('links_type',function ($query) {
$query->whereNotIn('external_count', [0,1]);
})->get();
Probably should add with('links_type') for eager_loading (N+1 problem):
$links = Link::with('links_type')->where('status','=','1')->where('user_id','=','1')
->whereHas('links_type',function ($query) {
$query->whereNotIn('external_count', [0,1]);
})->get();
maybe this could work.
before you must create hasMany relation for Link and name as type
$links = Link::where('status', 1)
->wherer('user_id', 1)
->whereHas('type', function($query) {
$query->where(
$query->where('links_type', 'external')->count(), '>', 2
);
})
->get();
Hello friends I have 2 Mysql tables with 1:N relationship between category and category_Dates
Category:
ID Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
category_Dates:
ID CatID Date
1 1 01-Jan-15
2 1 01-Jul-15
3 2 01-Jan-15
4 2 01-Apr-15
5 2 01-Jul-15
6 2 01-Oct-15
based on the category frequency I am entering number of records automatically in category_date. Eg
When category frequency = quarterly, I am entering 4 records in category_date with ID of that category. And dates will be entered later.
I am little confused if in case on wants to edit the frequency from halfyearly to yearly. How to change number of records. Please help with your valuable suggestions. I am using laravel 4 framework with mysql
best way would be with 3rd table joining Dates and Categories. See little carefully ,you can see its actually Many to Many relationship (N to N) as 1 category can have multiple dates. and one date may be part of multiple categories, like say 01-Jan-15 is part of Category 1 and 2 as well.
So use
category table
id Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
date table
id Date
1 01-Jan-15
2 01-Apr-15
3 01-Jul-15
4 01-Oct-15
categories_dates table
ID CatID Date_id
1 1 1
2 1 3
3 2 1
4 2 2
5 2 3
6 2 4
If you change the frequency in Category table, retrieve the update category_id,
delete all from category_dates where CatId=category_id then insert the new entries in category_Dates.
Hope this help.
I assume your models are Category and CategoryDates.
let's update category id 1 from Half-yearlyto to Quarterly
$query = Category::find(1);
$query -> Frequency = 'Quarterly';
$query -> save();
return $query -> id;
in the CategoryDates model you would delete the catID = 1 and insert new data
$catID = 1;
$query = CategoryModel::where('CatId',$catId) -> delete();
$data = ['CatId' => $catID,'date' => 01-Jan-15, ....];
CategoryModel::create($data);
of course assuming that you would return the newly updated category id to your controller and call a funtionn to do the update in your CategoryModel.
Hope this help.
My Question is simply how to insert data into the join table(user_book) without inserting a duplicate entry into the main table(book).
Mainly consider we have tree table below
id Users id Books id Users Books
1 Sam 1 B1 1 1 1
2 Ben 2 B2 2 1 3
3 Mike 3 B3 3 3 3
4 2 2
But the problem is when I am inserting a new book(ex Mike like B3) that exist in the Books table. The duplicate will appear in the books table and the above table will be like:
id Users id Books id Users Books
1 Sam 1 B1 1 1 1
2 Ben 2 B2 2 1 3
3 Mike 3 B3 3 3 4
4 B3 4 2 2
Is that make sense now what I am trying to resolve? Or maybe I can't have a unique list of books at all?
if I am going to insert
Given the database
users and books
users<--->books are related by users_books
we need to make sure that when we insert a book record to the db it is not a duplicate. Further, if the book exist, a relation will be inserted and not the book record . How can one do that?
One approach is to say
$m=new Book();
$m->where('id_book', $data['user_booklist'][$i]['id'])->get();
$u = new User();
$u -> where('id_user', $data['user_profile']['id'])-> get();
if(!$u->where_related($m))
{
$m -> name = $data['user_booklist'][$i]['name'];
$m -> id_book = $data['user_booklist'][$i]['id'];
$m -> save($u);
}
if (book->exist) in the "books" table
then check the relation and see if there is a relationship between users and books and if there is then don't insert it. Further do I need to change any thing in the mysql db structure to avoid this.
The above code is not working but should give an idea what I am talking about.
Update:
In summary, if two users liked the same book, I just want to insert a record(book) into the join table (users_books) and while not to creating a new record in the table. Using the unique sql tag did not work since it keeps unique list but it prevents from inserting the multiple relationships into the join table users_books.
You could do:
$b = new book();
$b->where('id_book', $data['user_booklist'][$i]['id'])->get();
// I believe you can do this as well, but I'm not sure:
// $b->where('id', $data['user_booklist'][$i]['id'])->get();
$u = new user();
$u -> where('id_user', $data['user_profile']['id'])-> get();
if( $b->exists() && $u->exists() )
{
// This saves the relationship between the book and the user
$b->save($u);
}
else
{
// Could not find the book or the user
}
You should check out the datamapper-manual on saving relationships.