I try create simple model with Laravel and Eloquent.
Here my code example:
composer.json
"laravel/framework": "4.1.*"
routes.php
Route::controller('items', 'ItemsController');
Route::get('item/{item}', array('as'=>'item', 'uses'=> 'ItemsController#getView'));
php artisan route:
| | GET item/{item} | item | ItemsController#getView | | |
| | GET items | | ItemsController#getIndex | | |
controllers/ItemsController.php
<?php
class ItemsController extends BaseController {
public function getIndex()
{
$items = Item::all();
return View::make('items.index')
->with('title', 'Index show')
->with('items', $items);
}
public function getView($id)
{
return View::make('items.view')
->with('title', 'View show')
->with('items', Item::find($id));
}
}
models/Item.php
<?php
class Item extends Eloquent {
protected $table = 'items';
}
DB: I have MySQL table "items" with 6 rows, for example:
+----+-----------+---------------------+
| id | name | created_at |
+----+-----------+---------------------+
| 4 | ironman | 2012-04-03 10:02:44 |
| 5 | robot | 2012-04-13 10:02:44 |
+----+-----------+---------------------+
When I try to GET mydomain/item/2
Laravel say:
Call to undefined method Item::find()
And GET mydomain/items/
Call to undefined method Item::all()
What I'm missed?
It sometimes happens to me when I am changing model and table names "on the fly", and when I do a lot of migration rollback. Try to rename you model name, it works for me in most cases.
Related
I'm struggling to connect three models in my Laravel app. The models are Bottle, Label and Spirit. I want to get all the labels based on bottle_id and spirit_id so I created a pivot table to store the relationships between Bottle-Label-Spirit. Please see below my current setup.
DB
+---------+--------+---------+-------------------------+
| bottles | labels | spirits | bottle_label_spirit |
+---------+--------+---------+-------------------------+
| id | id | id | id |
| name | name | name | bottle_id |
| | | | label_id |
| | | | spirit_id |
| | | | created_at |
| | | | updated_at |
+---------+--------+---------+-------------------------+
Where bottle_label_spirit is my pivot table
BOTTLE CLASS
class Bottle extends Model
{
public function labels() {
return $this->belongsToMany(Label::class)->withTimestamps();
}
public function spirits() {
return $this->belongsToMany(Spirit::class)->withTimestamps();
}
}
LABEL CLASS
class Label extends Model
{
public function bottles() {
return $this->belongsToMany(Bottle::class)->withTimestamps();
}
public function spirits() {
return $this->belongsToMany(Spirit::class)->withTimestamps();
}
}
SPIRIT CLASS
class Spirit extends Model
{
public function labels() {
return $this->belongsToMany(Label::class)->withTimestamps();
}
public function bottles() {
return $this->belongsToMany(Bottle::class)->withTimestamps();
}
}
QUESTIONS
So my questions are:
Is this the right approach to handle this manyToMany relationships?
If yes, how do i get all the labels where bottle_id = 1 and spirit_id = 1
You do not need a 4th table for this, you can accomplish all of this using hasManyThrough. This will allow you to query distant relationships.
UPDATE: The issue mentioned here has caused by the use of MariaDB instead of MySQL by XAMPP. I have followed the answer here to switch it to MySQL and it works like a charm.
This is regarding an e-commerce platform.
I have 2 data tables with 1 joining table for a many-to-many join. The idea is for Products to have many Special Offers running at any given time.
Tables
products
+-------+-------------------------------+
| id | name |
+-------+-------------------------------+
| 10001 | Apple iPhone 11 |
| 10002 | Samsung Galaxy S11 |
+-------+-------------------------------+
special_offers
+----+-------------------------------+
| id | name |
+----+-------------------------------+
| 1 | Awesome Offer |
| 2 | Year End Offer |
+----+-------------------------------+
product_special_offer
+------------+------------------+----------+
| product_id | special_offer_id | discount |
+------------+------------------+----------+
| 10001 | 1 | 10.0 |
| 10002 | 2 | 12.5 |
+------------+------------------+----------+
Models
Since the requirement is for a many-to-many relationship, I am using belongToMany method in my models.
Product
class Product extends Model
{
public function specialOffers()
{
return $this->belongsToMany(SpecialOffer::class)->withPivot('discount');
}
}
SpecialOffer
class SpecialOffer extends Model
{
public function products()
{
return $this->belongsToMany(Product::class)->withPivot('discount');
}
}
Controller
The following is the controller snippet.
ProductController
class ProductController extends Controller
{
public function index()
{
$product = Product::find(10001);
dd($product->specialOffers);
}
}
Results
The following is what Laravel returns.
Collection {#610 ▼
#items: []
}
The query it runs is mentioned below.
select `special_offers`.*, `product_special_offer`.`product_id` as `pivot_product_id`, `product_special_offer`.`special_offer_id` as `pivot_special_offer_id`, `product_special_offer`.`discount` as `pivot_discount` from `special_offers` inner join `product_special_offer` on `special_offers`.`id` = `product_special_offer`.`special_offer_id` where `product_special_offer`.`product_id` = 10001
This could work
class SpecialOffer extends Model
{
public function products()
{
return $this->belongsToMany(Product::class, 'product_special_offer','special_offer_id','product_id');
}
}
Make a third model to the connection table, and add the two relation. And it's will work.
class ProductSpecialOffer extends Model
{
public function products() {
return $this->belongsTo(Product::class);
}
public function specialOffers() {
return $this->belongsTo(SpecialOffer::class);
}
}
I have Two Table
1- projects
User with id 5 has created 3 project - which means he will have 3 unique conversation with our different agent
----------------------------------------
|id | user_id | title | time |
|1 | 5 | Example | 2018-06-30 |
|2 | 5 | Example | 2018-06-30 |
|3 | 5 | Example | 2018-06-30 |
----------------------------------------
2- conversation
-------------------------------------------
|id | project_id | user_one | user_two |
|1 | 1 | 5 | 3 |
|2 | 2 | 5 | 7 |
|3 | 3 | 5 | 10 |
-------------------------------------------
Whenever a project is created, a conversation is created with that project id, Now in Laravel i want to get that project detail using Eloquent Relationships.
User_one is the project creator and user_two is our agent assigned to that product.
This is What I've tried
class Chat extends Model {
public function project()
{
return $this->belongsTo('App\ProjectModel');
}
}
class ProjectModel extends Model
{
public $table = 'projects';
}
Here is the controller function
public function Progress($id){ // Id passed here is 2, so it should show detail of project number 2
return \App\Chat::find($id)->project()->get();
}
After all this I'm getting an error - Call to a member function project() on null
You can try like this with creating 2 Models Project and Conversation
table
conversations(id, project_id, creator, agent)
Project Model
public function conversations(){
return $this->hasMany('App\Conversation');
}
Conversation Model
public function project(){
return $this->belongsTo('App\Project', 'project_id');
}
public function creatorUser(){
return $this->belongsTo('App\User', 'creator');
}
public function agentUser(){
return $this->belongsTo('App\User', 'agent');
}
Fetch Data
public function Progress($id){ // Id passed here is 2, so it should show detail of project number 2
$chats = Conversation::with('project', 'creatorUser', 'agentUser')->where('project_id', 2)->get();
foreach($chats as $chat){
dd($chat->project); //it will always print same project because we have filter the conversation by project_id
dd($chat->creatorUser);
dd($chat->agentUser);
}
}
you can create a relation Along with specifying foreign Key and owner key like:
class Chat extends Model {
public function project()
{
return $this->belongsTo(App\ProjectModel::class, 'project_id', 'id');
}
}
and then you will be able to get:
\App\Chat::where('id', $id)->first()->project;
I have these tables:
Entries table
---------------------------------
| id | blog_id | title |
---------------------------------
| 1 | 1 | 1st Entry |
---------------------------------
Blogs Table
-----------------
| id | name |
-----------------
| 1 | 1stBlog |
-----------------
Field Groups Table
-------------------------
| id | blog_id | name |
-------------------------
| 1 | 1 | Group1 |
-------------------------
Fields Table
---------------------------------
| id | field_group_id | name |
---------------------------------
| 1 | 1 | field_1 |
---------------------------------
Values Table
------------------------------------------
| id | field_id | entry_id | value |
------------------------------------------
| 1 | 1 | 1 | Hello World |
------------------------------------------
Now on my Models I've set up these relationships:
class Entry extends Model
{
public function blog()
{
return $this->belongsTo(Blog::class);
}
}
class Blog extends Model
{
public function entries()
{
return $this->hasMany(Entry::class);
}
public field_group()
{
return $this->hasOne(FieldGroup::class);
}
}
class FieldGroup extends Model
{
public function fields()
{
return $this->hasMany(Entry::class);
}
public function blog()
{
return $this->belongsTo(Blog::class);
}
}
class Field extends Model
{
public function group()
{
return $this->belongsTo(FieldGroup::class, 'field_group_id');
}
public function values()
{
// this method should get the values from the Values table per entry id
return $this->hasManyThrough(Value::class, Entry::class, 'id', 'entry_id');
}
}
class Value extends Model
{
public function field()
{
return $this->belongsTo(Field::class, 'field_id');
}
}
Using this query I can
$entry = Entry::with('blog.field_group.fields')->find(1)
I can get the entry, along with its blog, field groups and fields. I want to get the values associated with the entry too,
$entry = Entry::with('blog.field_group.fields.values')->find(1)
I am having trouble on which relationship to use. Any help is much appreciated. I just started using laravel.
Try it...
Replace ID by field_id:
return $this->hasManyThrough(Value::class, Entry::class, 'id', 'entry_id');
Like this:
return $this->hasManyThrough(Value::class, Entry::class, 'field_id', 'entry_id');
Because you are using the standard laravel column names you can simplify even more:
return $this->hasManyThrough(Value::class, Entry::class);
See in: https://laravel.com/docs/5.1/eloquent-relationships#has-many-through
I think you should use 'foreign_key' with 'hasMany' and 'hasOne'.
return $this->hasMany('Comment', 'foreign_key');
class Blog extends Model
{
public function entries()
{
return $this->hasMany(Entry::class, 'blog_id');
}
public field_group()
{
return $this->hasOne(FieldGroup::class, 'blog_id');
}
}
refer
http://laravel.com/docs/4.2/eloquent#one-to-many
I have 3 models: Basket, Product and Asset.
A Basket can contain many Assets, and one asset can appear in multiple Baskets.
A Product can have many Assets, but an Asset can also be assigned to more than one Product.
The aim is to get Assets into a Basket while still knowing which Product it was added from.
The table structure I envision having is this:
-------------------------------------
| basket_id | asset_id | product_id |
-------------------------------------
| 1 | 1 | 1 |
| 1 | 3 | 1 |
| 1 | 15 | 2 |
| 2 | 23 | 1 |
| 2 | 3 | 1 |
| 3 | 79 | 3 |
-------------------------------------
I also envision a model setup of something like this:
class Basket extends Eloquent {
public function assets() {
return $this->belongsToMany('Asset');
}
}
class Product extends Eloquent {
public function assets() {
return $this->belongsToMany('Asset');
}
}
class Asset extends Eloquent {
public function products() {
return $this->belongsToMany('Product');
}
public function product() {
// This should return the product from the product_id column
}
}
I'm not sure how to go about writing Asset::product() so that it returns the corresponding Product.
I'd like to call something like Basket::find(1)->assets()->first()->product; to get the product that the first asset was added to the basket from.
Here's a small piece that does what you need
https://github.com/jarektkaczyk/Eloquent-triple-pivot
and thanks to your PR a package on packagist:
https://packagist.org/packages/jarektkaczyk/eloquent-triple-pivot