Populating a pivot table with Laravel/Eloquent - laravel

I have 8 tables: products, pests, actives, crops, active_product, pest_product, crop_product, and active_pest
I've built a form that loads information about a selected (agrichemical) product - in that form, the user selects the pests, actives, and crops associated with that product. When submitted, my existing code is saving the expected information in the products table and, through a set of "belongsToMany" relationships, the active_product, pest_product, and crop_product pivot tables are also correctly updated.
My problem is that I do not know how to use the actives and pests information (i.e. their respective id values) to add to/update the active_pest table.
I'd appreciate some direction.
The methods in my models are as follow:
product
public function Actives()
{
return $this->hasMany('App\Models\Active','active_product', 'product_id', 'active_id');
}
public function pest()
{
return $this->belongsToMany('App\Models\Pest','pest_product', 'product_id', 'pest_id');
}
public function active()
{
return $this->belongsToMany('App\Models\Active','active_product', 'product_id', 'active_id');
}
active
public function product()
{
return $this->belongsToMany('App\Models\Product', 'active_product', 'active_id', 'product_id');
}
public function pest()
{
return $this->belongsToMany('App\Models\Pest', 'active_pest', 'active_id', 'pest_id');
}
pest
public function active()
{
return $this->belongsToMany('App\Models\Active', 'active_pest', 'pest_id', 'active_id');
}
public function product()
{
return $this->belongsToMany('App\Models\Product','pest_product', 'pest_id', 'product_id');
}
public function crop()
{
return $this->belongsToMany('App\Models\Crop','crop_pest', 'pest_id', 'crop_id');
}
I am using BackPack for Laravel - my Product controller contains this function for updating:
public function update(UpdateRequest $request)
{
$redirect_location = parent::updateCrud($request);
return $redirect_location;
}
updateCrud is
public function updateCrud(UpdateRequest $request = null)
{
$this->crud->hasAccessOrFail('update');
$this->crud->setOperation('update');
// fallback to global request instance
if (is_null($request)) {
$request = \Request::instance();
}
// update the row in the db
$item = $this->crud->update($request->get($this->crud->model->getKeyName()),
$request->except('save_action', '_token', '_method', 'current_tab', 'http_referrer'));
$this->data['entry'] = $this->crud->entry = $item;
// show a success message
\Alert::success(trans('backpack::crud.update_success'))->flash();
// save the redirect choice for next time
$this->setSaveAction();
return $this->performSaveAction($item->getKey());
}
Thanks, Tom

you can use laravel's attach method like this:
$actives = App\Active::create([
'someColumn' => 'test',
'anotherColumn' => 'test',
]);
$pests = App\Pest::create([
'someColumn' => 'test',
'anotherColumn' => 'test',
]);
$actives->pest()->attach($pests);
^^^-relation name in model

Related

How to access a relationship through another relationship

I am working on a survey system and I have a problem accessing one relationship through another.
I have these models and these relationships
Post
id
survey_id
public function survey()
{
return $this->belongsTo(Survey::class);
}
Surveys
id
survey_type_id
public function surveyOptions()
{
return $this->belongsToMany(Survey_options::class);
}
public function surveyType()
{
return $this->belongsTo(Survey_type::class);
}
public function posts()
{
return $this->hasMany(Post::class);
}
Survey_types
id
public function surveyOptions()
{
return $this->belongsToMany(Survey_options::class);
}
Survey_options
id
survey_type_id
public function values()
{
return $this->hasMany(Option_value::class);
}
options_values
survey_options_id
survey_id
public function surveyOptions()
{
return $this->belongsTo(Survey_options::class);
}
Survey_Survey_options (pivot)
survey_id
survey_options_id
I need to do a query with eadger loading to bring me all the posts with survey, surveyOptions, withCount comments y options_values of each surveyOptions. Something like this:
$post->survey->surveyOptions->options_values_count
I have managed to create this query that works for me everything except fetching the option_values count from each SurveyOption. How can I do it?
$posts = Post::with([
'survey' => function ($query) {
$query->withCount('totalSurveys');
},
'survey.surveyOptions',
'image',
'categories'
])
->withCount('comments')
->get();

Getting extra fields from laravel api having belongstomany relationship

I have two data tables related to each other by the belongstomany relationship. And when I am fetching data from its api controllers with selecting only two column keys ['id','title'] yet it returns some extra data in the response object.
modelcode:
public function place(){
return $this->belongsToMany(Place::class,'city_place')->select(array('id', 'title'));
}
controller code:
public function ofcity($id)
{
$city=City::findOrFail($id);
return new CityResource( $city->place()->get());
}
enter image description here
You must indicate the name of the table in front of the fields.
model Place code:
protected $columns = ['places.id', 'places.title']; //all column for select
public function scopeExclude($query, $value = [])
{
return $query->select(\array_diff($this->columns, (array) $value));
}
model City code:
public function place()
{
return $this->belongsToMany(Place::class,'city_place', 'city_id', 'place_id');
}
controller code:
public function ofcity($id)
{
$cities = City::findOrFail($id)->place()->exclude(['featured_image'])->get()->toArray();
return response()->json(['cities' => $cities], 200);
}
In exclude skip all the fields that need not to be shown.
Thanks everyone here helping me out but none of the above solution worked..I figured it out after trying different functions and spending hours on this.
model Place code:
public function place(){
return $this->belongsToMany(Place::class,'city_place','city_id','place_id')->select(array('places.id', 'places.title'));
}
controller code:
public function ofcity($id)
{
$city=City::findOrFail($id);
return new CityResource( $city->place()->get()->map(function ($item,$key) {
return ['id' => $item['id'],'title'=>$item['title']];
})
);

Create new Post with default Category belongsToMany

I have a Post/Category manyToMany relations and would like to be able to attach a default category named "Uncategorised" to each new post that is created. How can I do that? A BelongsToMany method only works on the Details page, not on Create page.
BelongsToMany::make(__('Categories'), 'categories', Category::class),
You can also set default value to your database field so that you can omit passing category and will be taken default to Uncategorised like if you are using MySQL you can do it this way by creating migration
$table->text('category')->default(0);
Because the BelongsToMany not show on mode create in Post Nova model. So we have to make our custom Select, by add this code to your fields:
public function fields(Request $request)
{
if($request->editMode=="create"){
$categories = \App\Category::get(['id','name']);
$options = [];
foreach($categories as $value){
$options[$value->id] = $value->name;
}
return [
ID::make()->sortable(),
Text::make('Title'),
Text::make('Summary'),
Textarea::make('Content'),
Select::make('Categories', 'category_id')
->options($options)
->displayUsingLabels()
->withMeta(['value' => 1]) // 1 = id of Uncategorised in categories table
];
}
return [
ID::make()->sortable(),
Text::make('Title'),
Text::make('Summary'),
Textarea::make('Content'),
BelongsToMany::make('Categories','categories')->display('name'),
];
}
Don’t forget relationship function in both, Post and Category model:
class Post extends Model
{
public function categories(){
return $this->belongsToMany(Category::class, 'category_post', 'post_id', 'category_id');
}
}
And:
class Category extends Model
{
public function posts(){
return $this->belongsToMany(Post::class,'category_post', 'category_id', 'post_id');
}
}
Then, custom the function process the data on mode Create of Post resource page, it’s at nova\src\Http\Controllers\ResourceStoreController.php, change function handle to this:
public function handle(CreateResourceRequest $request)
{
$resource = $request->resource();
$resource::authorizeToCreate($request);
$resource::validateForCreation($request);
$model = DB::transaction(function () use ($request, $resource) {
[$model, $callbacks] = $resource::fill(
$request, $resource::newModel()
);
if ($request->viaRelationship()) {
$request->findParentModelOrFail()
->{$request->viaRelationship}()
->save($model);
} else {
$model->save();
// your code to save to pivot category_post here
if(isset($request->category_id)&&($resource=='App\Nova\Post')){
$category_id = $request->category_id;
$post_id = $model->id;
\App\Post::find($post_id)->categories()->attach($category_id);
}
}
ActionEvent::forResourceCreate($request->user(), $model)->save();
collect($callbacks)->each->__invoke();
return $model;
});
return response()->json([
'id' => $model->getKey(),
'resource' => $model->attributesToArray(),
'redirect' => $resource::redirectAfterCreate($request, $request->newResourceWith($model)),
], 201);
}
}
All runs well on my computer. A fun question with me! Hope best to you, and ask me if you need!
What I ended up doing was saving the data on Post Model in boot().
public static function boot()
{
parent::boot();
static::created(function (Post $post) {
$post->categories()->attach([1]);
});
}

How to perform CRUD operations in elasticsearch with codeigniter?

Here my screenshot :
I want the CRUD operation like that above mentioned image.Can anyone help me with the sample code for this?
Your Controller
//add new member
public function function_name()
{
//add all input fields here with key (example)
$params = array(
'emp_name' => $this->input->post('name'),
);
$add = $this->your-model-name->function_name($params);
}
//For delete member
public function function_name($id) //$id is the ID to delete member
{
$delete = $this->your-model-name->function_name($id);
}
//Update member
public function function_name($id) //$id is the ID to update member
{
//all input fields of member you want to update (i.e. name)
$params = array(
'emp_name' => $this->input->post('name'),
);
$update= $this->your-model-name->function_name($id);
}
Your Model
public function function_name($params) //For add member
{
return $this->db->insert('table-name', $params);
}
public function function_name($id) //For delete member
{
$this->db->where('column-name', $id);
return $this->db->delete('table-name');
}
public function function_name($id) //For update member
{
$this->db->where('column-name', $id);
$this->db->set('column-name', $value);
return $this->db->update('table-name');
}

Add default value to pivot table (users_roles) when creating a new user

Been searching the internet to get an answer to my problem but can't find it :-(
I created a Roles/Permissions ability in my Laravel project by taking a videocourse. It uses pivot tables.
My database contains the following standard Laravel tables after php artisan make:auth (and migrate):
users
password_resets
For the roles/permissions ability I created the following tables:
roles (id, name)
permissions (id, name)
roles_permissions (role_id, permission_id)
users_roles (user_id, role_id)
users_permissions (user_id, permission_id)
I also created a Trait:
<?php
namespace App\Permissions;
use App\{Role, Permission};
trait HasPermissionsTrait
{
public function givePermissionTo(...$permissions)
{
$permissions = $this->getAllPermissions(array_flatten($permissions));
if ($permissions === null) {
return $this;
}
$this->permissions()->saveMany($permissions);
return $this;
}
public function withdrawPermissionTo(...$permissions)
{
$permissions = $this->getAllPermissions(array_flatten($permissions));
$this->permissions()->detach($permissions);
return $this;
}
public function updatePermissions(...$permissions)
{
$this->permissions()->detach();
return $this->givePermissionTo($permissions);;
}
public function hasRole(...$roles)
{
foreach ($roles as $role) {
if ($this->roles->contains('name', $role)) {
return true;
}
}
return false;
}
public function hasPermissionTo($permission)
{
return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
}
protected function hasPermissionThroughRole($permission)
{
foreach ($permission->roles as $role) {
if ($this->roles->contains($role)) {
return true;
}
}
return false;
}
protected function hasPermission($permission)
{
return (bool) $this->permissions->where('name', $permission->name)->count();
}
protected function getAllPermissions(array $permissions)
{
return Permission::whereIn('name', $permissions)->get();
}
public function roles()
{
return $this->belongsToMany(Role::class, 'users_roles');
}
public function permissions()
{
return $this->belongsToMany(Permission::class, 'users_permissions');
}
public function giveRoleTo(...$roles)
{
$roles = $this->getAllRoles(array_flatten($roles));
if ($roles === null) {
return $this;
}
$this->roles()->saveMany($roles);
return $this;
}
public function withdrawRoleTo(...$roles)
{
$roles = $this->getAllRoles(array_flatten($roles));
$this->roles()->detach($roles);
return $this;
}
public function updateRoles(...$roles)
{
$this->roles()->detach();
return $this->giveRoleTo($roles);;
}
}
My UsersController look like this (the create method):
public function store(CreateUserRequest $request)
{
$user = User::create([
'achternaam' => request('achternaam'),
'voorletters' => request('voorletters'),
'district_id' => request('district_id'),
'gemeente_id' => request('gemeente_id'),
'minister_id' => request('minister_id'),
'periode_van' => request('periode_van'),
'periode_tot' => request('periode_tot'),
'email' => request('email'),
'password' => bcrypt(request('password')),
'active' => false
]);
return redirect('/home')->withInfo('Een account activatie mail is verstuurd.');;
}
What I would like to do is to give a newly created user a default role of user (id='10', name='user' in the users_roles table).
When I use the method roles() to create a new record for that newly created user I get an error saying that the column 'role' does not exist in the roles table. Which is true because it only has an id & name column.
Can someone tell me why? And even better give me some code example to fix this problem?
Thanks in advance.

Resources