I have a model named Point having the following fields:
name
description
lat
lng
The fields "name" and "description" can be in several languages, so I created two tables for points and their details.
Schema::create('points', function (Blueprint $table) {
$table->id();
$table->float('lat');
$table->float('lng');
$table->timestamps();
Schema::create('point_details', function (Blueprint $table) {
$table->id();
$table->integer('point_id');
$table->string('name');
$table->string('description');
$table->string('lang');
There is an index unique on point_id/language.
In the model files I have One To Many relationships
class Point extends Model
{
public function details()
{
return $this->hasMany(PointDetail::class);
}
}
class PointDetail extends Model
{
public function point()
{
return $this->belongsTo(Point::class);
}
}
Now I want to get the Point with details based on User language. I do so in the PointController:
class PointController extends Controller
{
public function show($id)
{
$point = Point::with(['details' => function($query) {
$query->where(
'lang', Auth::user()->lang ?
Auth::user()->lang :
'it');
}])->find($id);
return view('points.show',compact(['point']));
}
}
Can I avoid the "with" clause in the Controller? Maybe making the right query in the Point model file. I'm looking for a way to return the point with one detail associated with it, based on language of the Auth::user().
Thanks for any suggestion.
you can add query to relationship method in point class to details method
like that :
class Point extends Model
{
public function details()
{
return $this->hasMany(PointDetail::class)->where('lang', Auth::user()->lang);
}
}
Related
Below are all of the models, migrations and controller.
Donation Model
class Donation extends Model
{
protected $guarded =[];
public function users(){
return $this->hasMany(User::class);
}
public function items(){
return $this->belongsTo(DonationItems::class);
}
}
Donation Items Model:
class DonationItems extends Model
{
protected $guarded=[];
public function donation(){
return $this->hasMany(Donaition::class);
}
}
Donation Items Migration:
public function up()
{
Schema::create('donation_items', function (Blueprint $table) {
$table->id();
$table->string('category');
$table->timestamps();
});
}
Donation Migration:
public function up()
{
Schema::create('donations', function (Blueprint $table) {
$table->id();
$table->string('item');
$table->unsignedInteger('user_id');
$table->unsignedInteger('donation_item_id');
$table->timestamps();
});
}
In my controller I want to access the items as follows:
$don = Donation::all();
$don->items;
But I'm unable to achieve this.
Its not working because laravel follows one rule for relationships:
Remember, Eloquent will automatically determine the proper foreign key column on the Comment model. By convention, Eloquent will take the "snake case" name of the owning model and suffix it with _id. So, for this example, Eloquent will assume the foreign key on the Comment model is post_id.
So you can try by supplying local and foreign id
So it would look something like this
Donation Model
class Donation extends Model
{
protected $guarded =[];
public function users(){
return $this->hasMany(User::class);
}
public function items(){
return $this->belongsTo(DonationItems::class, 'donation_item_id', 'id');
}
}
Donation Items Model:
class DonationItems extends Model
{
protected $guarded=[];
public function donation(){
return $this->hasMany(DonationItems::class, 'id', 'donation_item_id');
}
}
I am writing from my head you might need to swap local and foreign ID's
I'm trying to create a system to log all bookings for a few airbnb hosts, at first I had two models Home and Guest, where a home can have many guests and a guest could book for many homes,
then I thought about creating a guest_home pivot table to link both tables... then things got complicated in my head, what about a Booking model, and (have that booking model act as a pivot table ?) , to me doing new Booking() seemed better than attaching ids to home model?
How could you guys go about this, it's making my brain malt right now...
I thought of doing something like this in my BookingController:
public function createBooking(Request $request)
{
$guestIds = Guest::latest()->take(3)->pluck('id');
$home = Home::findOrFail($request->input('home_id', 2));
$booking = new Booking();
$booking->home_id = $home->id;
$booking->guests()->attach($guestIds);
$booking->save();
return response()->json([
'booking' => $booking,
]);
}
Should I create home_guest pivot table, is a pivot table even needed? what models would I link, please bear with me, so far this is what I got:
Models
class Guest extends Model
{
public function bookings()
{
return $this->belongsToMany('App\Models\Home', 'bookings', 'guest_id', 'home_id');
}
}
class Home extends Model
{
public function guests()
{
return $this->belongsToMany('App\Models\Guest', 'bookings', 'home_id', 'guest_id');
}
public function bookings()
{
return $this->hasMany('App\Models\Booking');
}
}
class Booking extends Model
{
//Is Booking needed or I could make a pivot table like home_guest called 'bookings' ?
public function guests()
{
return $this->belongsToMany('App\Models\Guest', 'booking_guest', 'booking_id', 'guest_id');
}
}
Migrations:
Schema::create('bookings', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('home_id')->index();
$table->foreign('home_id')->references('id')->on('homes')->onDelete('cascade')->onUpdate('cascade');
$table->unsignedInteger('guest_id')->nullable()->index();
$table->foreign('guest_id')->references('id')->on('guests')->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
Schema::create('homes', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('host_id')->index();
$table->foreign('host_id')->references('id')->on('hosts')->onDelete('cascade')->onUpdate('cascade');
$table->string('fullAddress')->unique();
$table->integer('rooms')->unique();
$table->timestamps();
});
Schema::create('guests', function (Blueprint $table) {
$table->increments('id');
$table->string('fullName')->unique();
$table->string('identificationType')->unique();
$table->text('country')->nullable();
$table->timestamps();
});
hey guys i have a confusing question
I have 3 tables
basket_lists (carts)
basket_items (carts_item)
products
with this migrate
'basket_lists':
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->boolean('active');
$table->timestamps();
basket_items:
$table->bigIncrements('id');
$table->unsignedBigInteger('product_Id');
$table->unsignedBigInteger('basket_list_id');
$table->timestamps();
products:
$table->bigIncrements('id');
$table->string('title');
$table->text('description');
$table->bigInteger('amount');
$table->timestamps();
I have some products in my table , when i search (query) {
BasketList::where('active', '=', 1)->with('basketItems.products')->get();
it only gives me the first basketlist products (where id = 1)
if i insert new basketlist and set the first basketlist to (active = 0) and second one to (active = 1) it will not show any products.
Here is my model classes :
class BasketList extends Model
{
public function basketItems()
{
return $this->hasMany(BasketItem::class ,'basket_list_id' );
}
}
class BasketItem extends Model
{
public function products()
{
return $this->hasMany(Product::class,'id' );
}
public function basketList()
{
return $this->belongsTo(BasketList::class);
}
}
public function basketItem()
{
return $this->belongsTo(BasketItem::class ,'product_id');
}
You must change your relationship to belongsTo()
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BasketItem extends Model
{
//
protected $table = 'basket_items';
public function product()
{
return $this->belongsTo(Product::class, 'product_id','id' ); // Watch out for the case sensitive. how did you wright product_id in your migration. (product_id or product_Id)
}
You break Laravel default naming conventions for foreign keys 'product_Id'
It must be 'product_id'
Eloquent determines the foreign key of the relationship based on the
model name. In this case, the BasketItem model is automatically
assumed to have a 'product_id' foreign key. If you wish to override this
convention, you may pass a second argument to the hasMany method:
Fix
App\BasketItem.php
public function product()
{
return $this->belongsTo(Product::class, 'product_Id','id' );
}
Check Documentation
Usage
BasketList::where('active', '=', 1)->with('basketItems', 'basketItems.product')->get();
I want to return the projects of the authenticated user, but am not getting any. I know the records exist in the database.
This is my model Project:
public function users(){
return $this->hasMany(User::class);
}
this is my model User:
public function projects(){
return $this->hasMany(Projet::class,'user_id');
}
and this is the controller function :
public function projetuser(){
$user = User::find(auth()->user()->id);
return $user->projects;
}
and this my user_projet migration:
public function up()
{
Schema::create('user_projet', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('projet_id');
$table->foreign('projet_id')->references('id')->on('projets')->onDelete('cascade');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('membre')->nullbale();
$table->timestamps();
});
}
You are defining a many-to-many relationship incorrectly. Use belongsToMany() instead of hasMany(). Because your pivot table name is not standard (it should be alphabetic order projet_user) you need to include it in the relationship definition as well.
<?php
use Illuminate\Database\Eloquent\Model;
class Projet extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'user_projet');
}
}
class User extends Model
{
public function projets(){
return $this->belongsToMany(Projet::class, 'user_projet');
}
}
Now in your controller you can do this:
public function projetuser(){
return auth()->user->projets;
}
Your question seems to vary between "projet" and "project." I assumed "projet" was the correct spelling, but try to keep this consistent.
Please note also the typo in your migration: nullbale.
I am looking for a solution for storing comments in the database, but it is not difficult at all:
In one table wants to write comments from several modules on the website.
I am currently creating a table using code 'comments table':
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('module_id')->unsigned();
$table->integer('parent_id')->unsigned();
$table->text('body');
$table->timestamps();
});
}
Comments modules table:
public function up()
{
//
Schema::create('comment_module',function (Blueprint $table){
$table->increments('id');
$table->string('title',190);
$table->string('name',190)->unique();
$table->text('body');
$table->timestamps();
});
}
for now everything is okay, but i have problem with select all comments for each blog post,gallery, etc..
blog, gallery - name of modules.
code for Map.php model
public function comments(){
return $this->hasMany(Comment::class,'module_id');
}
CommentModule.php model
public function comments(){
return $this->hasMany(Comment::class,'module_id');
}
Comment.php
public function module(){
return $this->belongsTo(CommentModule::class);
}
and now how to pass a 'mmodule_id' ?
normal use with any relationships for one table will be like that:
$map->comments->body . . etc.
but for that construction don`t work, yes of course i can use raw query and use join, right ?
Is any option to use a Eloquent?
IMHO for what I understood you want to attach comments to more than one Eloquent Model. There is a clean example in the laravel docs with Polymorphic Relations
As summary you have to add two fields on the comments table: commentable_id(integer) and commentable_type (string).
After that you declare the relation on the Comment model:
public function commentable()
{
return $this->morphTo();
}
And you can use the comments() relation in each model you want to attach comments, i.e.:
class Post extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
class Map extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
Now you can retrieve comments as usual:
$post->comments;
To attach a new comment to a parent:
$post->comments()->create([array of comment attributes]);