I've got the following tables:
products (
id
)
attributes (
id
name
value
)
products_attributes (
product_id,
attribute_id
)
And I need to be able to query for all of the attributes of a specific product. I tried doing this with the FLUENT QUERY BUILDER but I'm getting lost in my own code.
Can someone help me out with an example?
Usually you would create models for both of your entities, in which you can specify the relationships:
class Product extends Eloquent
{
protected $table = 'products';
public function attributes()
{
return $this->belongsToMany('Attribute', 'products_attributes');
}
}
class Attribute extends Eloquent
{
protected $table = 'attributes';
public function products()
{
return $this->belongsToMany('Product', 'products_attributes');
}
}
The belongsToMany() method sets up a many-to-many relationship. The first parameter specifies the related model class name, the second one the name of the database table that holds the connections between the two entities.
To find a product with ID 1234, you would fetch it like this:
$product = Product::find(1234);
You can then magically access all of its attributes like this:
$attributes = $product->attributes;
For more information, you can refer to the documentation.
Related
I have two tables in Laravel Eloquent:
UserCategory:
id | user | category
and
Category:
id | name
UserCategories relates to Category trough belongsTo:
class UserCategory extends Model
{
public function category()
{
return $this->belongsTo('App\Category', 'category');
}
}
But when I try to get UserCategories with Categories I got integer value (instead of Category model)
$categories = [];
$userCategory = UserCategory::where('user', $user->id)->with('category')->get();
foreach($userCategory as $item) {
$categories[] = $item->category->name;
}
When I try to get the category's name I see the second error:
Trying to get property 'name' of non-object
Curious thing, that when I use dd($item) I see that $item has correct relation to Category object, but dd($item->category) returns integer value (category id) instead of category model.
You have conflicting names. You have both a category column, and a category relationship. By saying $item->category its showing you the category column value. Try changing the relationship name to something else and see if that works.
The best practice would be to use a column name of category_id, but if changing the column name isn't feasible in your situation then the relationship name will work just as well.
Change your relation name or id name here because here your relation name & coloumn name is same
class UserCategory extends Model
{
public function category()
{
return $this->belongsTo(Category::class, 'category');
}
}
I have a table of articles defined by their ID, name, price and category_ID and a table of categories defined by category_ID and name.
I want to select into my controller, the list of articles, along with the category name.
How to do that?
My answer assumes you keep the models in App\Models folder
In your Articles model define the following method.
public function category()
{
return $this->belongsTo('App\Models\Category');
}
You can access it now via $myArticle->category->name;
Make sure in Categories model the correct table is defined, based on your question i can not make up the categorie table.
Put $table = 'categories'; in the category model or whatever the table name is.
with raw SQL
$query = "SELECT articles.* , categories.name AS categoryName FROM articles JOIN categories ON articles.category_ID = categories. category_ID"
$result = \DB::select(SQL);
dump($result)
or
with Eloquent you can add a method to your model to return relationship , let's call it category
class Article extends Model {
public function category(){
return $this->hasOne("App/Category" , "category_ID" , "category_ID");
}
}
now you can do this
$article = Article::find(1);
dump($article->category->name);
checkout hasOne method from the docs
I've just started using Eloquent ORM (Without Laravel) and I am having issues with the many to many relationships.
I have a table where I store Families (Article categories), another one for the Articles, and a third one as a "pivot". I want to be able to get all the articles a Family has, and all the families an article belongs to. So I have coded this models.
Families
class Families extends Model {
public $table = 'Families';
public function Articles() {
return $this->belongsToMany('Articles', 'articles_families', 'families_id', 'articles_id');
}
}
Articles
class Articles extends Model {
public $table = 'Articles';
public function Families() {
return $this->belongsToMany('Families', null, 'articles_id', 'families_id');
}
}
Then I am trying to retrieve the data like this:
$families = Families::all();
echo $families[1]->Articles;
However, it just returns an empty array, when it should return a couple of articles. I have tripled checked that all the values are correct in the three tables. If I echo the Eloquent query debugger I can see that it is looking for a null value and I'm pretty sure that's the problem, but I don't quite know how to fix it. Here:
{"query":"select * from `Families`","bindings":[],"time":49.13},{"query":"select `Articles`.*, `articles_families`.`families_id` as `pivot_families_id`, `articles_families`.`articles_id` as `pivot_articles_id` from `Articles` inner join `articles_families` on `Articles`.`id` = `articles_families`.`articles_id` where `articles_families`.`families_id` is null","bindings":[],"time":38.93}
The null value is at the end of the last query.
I just found the solution myself. As my primary key columns are called Id, and Eloquent by default assumes the primary key is called id, I needed to override that by adding a class property protected $primaryKey = "Id"; and it now retrieves the data properly.
I want to make a relation with 3 table using ORM but cant. My tables
User table
id | userame | name |
1 Ellie Elen
2 Pol Paul
record table
id | user_id| item_id| hour|
1 2 1 3
2 2 2 5
Item table table
id | title
1 item 1
2 item 2
I am using this logic but not work properly
class User Extends Eloquent {
public function record()
{
return $this->hasMany('VolunteerRecord');
}
}
class VolunteerRecord Extends Eloquent {
function item() {
return $this->hasMany('VolunteerItem');
}
}
I cant understand how to do it?
It seems like you want a Many-To-Many relationship between Users and Items but you also want to track hours on the pivot table. So first, you'll define the many-to-many relationships using belongsToMany(), and you'll tell Laravel that you have extra data on your pivot table with the withPivot() function. Your classes will look like this:
class User extends Eloquent {
protected $table = 'users';
public function items() {
return $this->belongsToMany('Item', 'records')->withPivot('hour');
}
}
class Item extends Eloquent {
protected $table = 'items';
public function users() {
return $this->belongsToMany('User', 'records')->withPivot('hour');
}
}
Then, to access the hour field you would do this:
$user = User::first(); // First User
$item = $user->items()->first(); // User's first Item
$hour = $item->pivot->hour; // The 'hour' on the User-Item relationship
Also, your current column naming scheme is correct for Laravel so don't feel like you need to change it. If you change your column names, then you'll need to define them in the belongsToMany() method like this:
$this->belongsToMany('ModelName', 'pivot_table', 'foreign_key', 'other_key');
// For example, in Items::users() you would have this:
$this->belongsToMany('User', 'records', 'users_id', 'items_id');
Finally, I'm assuming that your tables are named users, items, and records. If they are not, then just replace all instances of users, items, and records with your actual table names.
Based on your table names, I'd suggest the following, first of all, change your record table as follows:
id | users_id| items_id| hour|
1 2 1 3
2 2 2 5
And these are the classes for your models:
class Users extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
public function records()
{
return $this->hasMany('Records');
}
}
class Records extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'records';
public function record()
{
return $this->hasOne('Users');
}
public function item()
{
return $this->hasOne('Items');
}
}
class Items extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'items';
public function records()
{
return $this->hasMany('Records');
}
}
These contain the relations for your models.
If you were to select a few records, for each record you can get the user and the item. If you were to select an item, and all records for that item. You can also get the user for each record.
In User Model
public function images()
{
return $this->belongsToMany('Item')->withPivot('hour');
}
In user controller
public function view($username)
{
$user = User::where('name',$username)->firstOrFail();
return View::make('view')->with('user',$user);
}
In view
#foreach ($users->items as $item)
name: {{$image->title}}<br>
hour: {{$image->pivot->hour}}<br>
#endforeach
I am trying to use Eloquent to get a specific product that has a brand_id column that maps to a brands table, the brand array is coming back empty.
Is there anything obvious here that needs to be changed?
$product = Product::with('images')->with('brand')->select($fields)->where('display', '=', 1)->find($id);
//Product model
class Product extends Eloquent {
...
public function brand()
{
return $this->belongsTo('Brand');
}
//Brand model
class Brand extends Eloquent {
...
public function products()
{
return $this->hasMany('Product');
}
You have this:
$product = Product::with('images', 'brand')
->select($fields)
->where('display', 1)
->find($id);
You are getting null for brand and it could be because you have some specific fields and most probably you didn't select the foreing_key from the products table that creates the relationship with Brand, so if your products table contains the foreign_key (probably brand_id) of brand table then you have to select that foreign_key from the products table too. So, just add that foreign_key/brand_id in the $fields variable. Without the relation builder key (FK) the Brand won't be loaded.