Laravel Relationship Issues : Laravel 5.4 - laravel

I have 2 tables in my application... Users Conventioners
I have users id in the conventioners table and i want to access their genders from the Users table....
I have like 10 user ids in the conventioners table and 20 users in the users table...
Please how do I access all their genders in the users table...
$conventioners->users()->gender
Conventioners is an instance of the Conventioner Model which contains a relationship **belongsToMany
Thanks alot guys
Here is my Conventioner Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Conventioner extends Model
{
/**
* #var string
*/
protected $table = 'conventioners';
/**
* #var array
*/
protected $fillable = [
'user_id','year','church_id','convention_id'
];
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\User');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users()
{
return $this->hasMany('App\User');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function convention()
{
return $this->belongsTo('App\Convention');
}
}
Here is my ConventionController method called Convention...
It retrieves the details for the current convention
public function convention($slug)
{
if(!$this->admin()) return redirect()->back();
$convention = Convention::where('slug', $slug)->first();
$participants = Conventioner::where('convention_id', $convention->id)->get();
$conventioner = [];
foreach($participants as $participant)
{
$thisUser = [];
$thisUser['data'] = User::withTrashed()->where('id', $participant->user_id)->first();
$thisUser['convention'] = $participant;
array_push($conventioner, $thisUser);
}
var_dump($participants->users()->pluck('gender')->all());
return view('dashboard/conventions/convention', [
'convention' => $convention,
'user' => Auth::user(),
'conventioners' => $convention->conventioners(),
'participants' => $conventioner
]);
}

The problem is that users is a collection not an individual that you can call gender on. If you want a list of all the genders you can use the following:
Conventioner::where('convention_id', $convention->id)->with('users')->get()
$conventioners->pluck('users')->pluck('gender')->all();
This will return an array of the genders. You can read more about pluck here.
The pluck method retrieves all of the values for a given key

Related

Eloquent relationship returning all when ID doesn't match

For some reason my relationship is fetching all from the corresponding table when I dump it, however dumping the result does not show these rows.
The slider ID does not match the slider_id within the settings table.
So the following works fine, as expected the settings is an empty array:
/**
* #return HasOne
*/
public function slider(): HasOne
{
return $this->hasOne(Slider::class)->withDefault(
(new Slider())->attributesToArray()
);
}
Result:
{
"name": "media-slider",
"settings": []
}
However when I dump within the attribute I get all the rows from the settings table, when this query should be getting all settings where the slider_id matches the current slider, which has a different ID.
<?php
namespace App\Models\Media;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
class Slider extends Model
{
/** #var string[] */
protected $appends = [ 'settings' ];
protected $defaults = [
'test' => [
'id' => 0,
'name' => 'default name',
]
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->attributes = $this->defaults['test'];
}
/**
* #return HasMany
*/
public function settings(): HasMany
{
return $this->hasMany(SliderSetting::class);
}
/**
* Get the slider settings, extract the value and key by the key, also
* group if multiple setting groups are required.
*
* Perform this logic here so data can be used directly by the JavaScript.
*
* #return \Illuminate\Database\Eloquent\Collection|Collection
*/
public function getSettingsAttribute()
{
dd($this->settings()->get()); // This should be empty!
return $this->settings()->get()
->groupBy('group')
->map(static function ($group) {
$group = $group->keyBy('key');
return $group->map(static function ($setting) {
return $setting->getAttribute('value');
});
});
}
}
Edit
/**
* #return HasMany
*/
public function sliderSettings(): HasMany
{
dd($this->hasMany(SliderSetting::class)->toSql());
return $this->hasMany(SliderSetting::class);
}
The above outputs:
select * from slider_settings
Shouldn't it be the following?
select * from slider_settings where slider_settings.slider_id = ?

Laravel 6 - Accessor appends not called in relationships

I use Laravel 6 and I want access to avatar attribute from user when I use posts() relation.
User model:
/**
* #var array
*/
protected $appends = [
'avatar',
];
/**
* #return HasMany
*/
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
/**
* #return string
*/
public function getAvatarAttribute(): string
{
return sprintf('https://secure.gravatar.com/avatar/%s?s=500', md5($this->email));
}
The code of my controller:
$topic = Topic::where('slug', $slug)->firstOrFail();
foreach ($topic->posts()->get() as $post) {
dd($post->user->avatar); // return null
}
Post model:
/**
* #return BelongsTo
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
I get the name of user with $post->user->name but avatar attribute is not called.

Appending Eloquent Attributes/Modified Relation Date on Query Building / Code Optimization

I'm looking for a solution to optimize my Code using Laravel Eloquent.
My issue is that I want to add Attributes conditionally, and this Attributes is basically the a transformed many-to-many relationship.
At the moment I have this in my controller (simplified):
<?php
namespace App\Http\Controller;
/**
* Class Category
*/
class Category extends Controller
{
/**
* #return Collection
*/
public function index()
{
return Category::withCount('countries')->get();
}
/**
* #param int $id
*
* #return Category
*/
public function show($id)
{
$result = Category::where('id', $id)
->with('countries')
->firstOrFail();
$result->countries_list = '';
return $result;
}
}
My Category model looks like this (simplified):
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class Category
*/
class Category extends Model
{
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'countries',
];
/**
* #return string
*/
public function getCountriesCountAttribute()
{
return trans_choice('labels.countries', $this->original['countries_count']);
}
/**
* #return
*/
public function getCountriesListAttribute()
{
return $this->countries->pluck('alpha_2');
}
/**
* Get the related Countries.
*/
public function countries()
{
return $this->belongsToMany(
Country::class,
'category_country',
'category_id',
'country_id'
);
}
}
The Country Model is just a list of Countries with id, name, the Alpha2 Code, etc. I can't use the protected $appends to add countries_list because than the the list would be always included.
I also can't change my Countries model because this is used in several other occurrences.
What I'm looking for is a way to optimize the code in the controller to this:
<?php
namespace App\Http\Controller;
/**
* #return Collection
*/
public function index()
{
return Category::withCount('countries')->get();
}
/**
* #param int $id
*
* #return Category
*/
public function show($id)
{
return Category::where('id', $id)
->withAttribute('countries_list') // An array of all country aplha 2 codes
->firstOrFail();
}
You can access the countries_list attribute after querying (don't include it in your query).
public function show($id)
{
$category = Category::findOrFail($id);
$list = $category->countries_list; // this calls getCountriesListAttribute()
}

laravel 4 - inserting of multiple fields in array

The following function in laravel stores my form input. I can't get it to store anything other than the author id and the title. It just won't store the keywords.
Below is the function in my Postcontroller.php
public function store()
{
$input = Input::all();
$rules = array(
'title' => 'required',
'text' => 'required',
);
$validation = Validator::make($input, $rules);
if ($validation->fails()) {
return Redirect::back()->withErrors($validation)->withInput();
} else {
// create new Post instance
$post = Post::create(array(
'title' => $input['title'],
'keywords' => $input['keywords'],
));
// create Text instance w/ text body
$text = Text::create(array('text' => $input['text']));
// save new Text and associate w/ new post
$post->text()->save($text);
if (isset($input['tags'])) {
foreach ($input['tags'] as $tagId) {
$tag = Tag::find($tagId);
$post->tags()->save($tag);
}
}
// associate the post with user
$post->author()->associate(Auth::user())->save();
return Redirect::to('question/'.$post->id);
}
}
Post.php (model)
<?php
class Post extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'posts';
/**
* Whitelisted model properties for mass assignment.
*
* #var array
*/
protected $fillable = array('title');
/**
* Defines a one-to-one relationship.
*
* #see http://laravel.com/docs/eloquent#one-to-one
*/
public function text()
{
return $this->hasOne('Text');
}
/**
* Defines an inverse one-to-many relationship.
*
* #see http://laravel.com/docs/eloquent#one-to-many
*/
public function author()
{
return $this->belongsTo('User', 'author_id');
}
/**
* Defines a many-to-many relationship.
*
* #see http://laravel.com/docs/eloquent#many-to-many
*/
public function tags()
{
return $this->belongsToMany('Tag');
}
/**
* Defines an inverse one-to-many relationship.
*
* #see http://laravel.com/docs/eloquent#one-to-many
*/
public function category()
{
return $this->belongsTo('Category');
}
/**
* Defines a polymorphic one-to-one relationship.
*
* #see http://laravel.com/docs/eloquent#polymorphic-relations
*/
public function image()
{
return $this->morphOne('Image', 'imageable');
}
/**
* Defines a one-to-many relationship.
*
* #see http://laravel.com/docs/eloquent#one-to-many
*/
public function comments()
{
return $this->hasMany('Comment');
}
}
You are stopping the mass assignment of keywords with your model settings.
Change
protected $fillable = array('title');
to
protected $fillable = array('title', 'keywords');

pivot table in laravel 4 insertion

hey guys im new in laravel and i was trying to insert into my pivot table. i have this structure in my database
the departments table belongs to many categories and same as category so i have this models
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Departments extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'departments';
protected $fillable = ['department_name'];
public $timestamps = false;
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
public function categories()
{
return $this->belongsToMany('Categories');
}
}
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Categories extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'categories';
protected $fillable = ['name'];
public $timestamps = false;
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
public function department()
{
return $this->belongsToMany('Departments');
}
}
then i have a query in my controller like this
$messages = array(
'required' => 'Please Fill the required field',
'unique' => 'Name Already exist'
);
$catName = Input::get('categoryName');
$deptId = Input::get('deptId');
$validation = Validator::make(Input::all(),[
'categoryName' => 'required|unique:categories,name' ], $messages);
if($validation->fails()){
return array('error' =>$validation->messages()->all() );
}else{
$findDepartment = Departments::find($deptId);
$saveCat = $findDepartment->categories()->insert(array('name' => $catName));
}
but then when i checked the tables it adds up on the categories table but nothing is added in the category_department. do i miss any codes? and also i had an error last time I was trying to migrate my pivot table the error was this.
can you help me guys on what i am missing? tnx for the help in advanced.
First, you should name your model classes as singular: Category, Department.
Then try to declare your relationships with the pivot table name:
public function categories()
{
return $this->belongsToMany('Category', 'category_department');
}
and
public function departments()
{
return $this->belongsToMany('Departments', 'category_department');
}
now, to insert new data, try attach:
$findDepartment = Department::find($deptId);
$category = Category::where('name', '=', $catName)->first();
$saveCat = $findDepartment->categories()->attach($category->id);

Resources