Jenssegers MongoDB dot notation in fillable - php

I'm trying to get the dot notation working in Jenssegers MongoDB package for Laravel. According this issue it's already been implemented:
link
But it doesn't seem to work in the latest version.
protected $fillable = ['title', 'some.data'];
Doesn't work. But if I open it all up it works fine.
protected $guarded = [];
So that works, not sure if this feature is still there or I need to pre filter my fields manually for now?

Nested fields are not currently supported in $fillable.
Unfortunately this means you have to do it manually. There are two ways to go:
If you have an embedded Some model, you can set $fillable on that, create/fill it with new data, then attach it to the parent model.
If you don't have/want a whole separate model for your subdocument, you would have to define e.g. $someFillable = ['data']; and use that to filter your new $some data prior to manually setting it on the model. You can basically just copy how Eloquent does it in its fill method.

Related

Specific question Laravel Database Homepage

I started using Laravel few days before.
I'm actually struggling with a problem, I created a homepage and I want to replace some text of the page with content from my database.
So how do I create a model/controller, and after that I will make an admin panel, so I can edit them.
The only tutorials/docs I see are for making a form/post to create users
Example
In basic php it's easy you just do a pdo connection and then a fetch and you use your date as you want. How do you do it in laravel ?
To fetch data from the DB in Laravel can be done in 1 of two ways, 1. using a Model (the best way) or using a Query Builder, which is much more familiar to those migrating from pure PHP.
Using a Model
Create a model using php artisan make:Model (change Model with a name of your choosing) then open the model once created (found in app/Http/Models) and add the following under use HasFactory;:
protected $table = 'your_table_name';
protected $primaryKey = 'id'; // This is the column you usually set to PRIMARY
public $timestamps = true;
protected $fillable = [
'table_column',
'table_column',
];
To use the Model, import it into your Controller file like so use App\Models\Model; and then use it as so:
$flights = Flight::where('destination', 'Paris')->get();
Learn more about Models in Laravel here.
Using a Query Builder, not best practice
Import the DB facade in the controller like so use DB; then call upon it like so:
$db = DB::table('users')->where('name', 'John')->first();
Learn more about the Query Builder here.
I hope this helps, if not let me know how I can assist further.

Laravel - Update $guarded array based on different config

I have one model and one controller and multiple configurations.
If I'm on config #1 my models $guarded property should be
$guarded = ['foo', 'bar'];
If I'm on config #2 my models $guarded property should be only
$guarded = ['foo'];
The config loaded is dependant on a domain/subdomain.
In my controller I have an import function which takes an array of data. 4 or so of the fields need to go to one table which is common across all configs and the remaining values(which are variable depending on the config loaded) need to go into a separate pivot table. So one config might have 8 fields but another may have 9 or more / less.
I've tried to remove the variable fields from the insert into the first table with guarded with something similar to the code here. After which I take the variable fields and insert into the other table.
protected $guarded = ['some', 'common', 'guarded', 'fields'];
function __construct()
{
$this->guarded = array_merge($this->guarded, config('custom_fields_for_domain'));
}
While I can dd($this->guarded) directly after and see the variable fields correctly in the model, I receive errors when trying to import into the first table as it's still trying to import all the variable fields rather than just the 4 or so fields I want.
If I manually add in all the variable fields, it works fine, so it seems that modifying $guarded even as early on as in the constructor doesn't work. It this correct? Is there a better way to modify the $guarded values based on different configurations?
I've not tried yet, but would I be better off using $fillable for just the fields I know are constant?

How to add value of guarded fields in database

I am using laravel 5.3 and in my custom model, I have some guarded fields like following.
protected $guarded = ['id', 'tnant_id', 'org_id', 'fac_id', 'slug', 'created_at', 'updated_at', 'deleted_at'];
Now When I try to add record using following.
CUSTOM::create(['tnant_id'=>123]);
It returns me following error.
Field 'tnant_id' doesn't have a default value.
Setting field default value in table will not work because each time I am passing value and it is giving error for all guarded fields.
So how I can add guarded fields value in database? In update query, It is allowing to update but on create it gives error.
You simply can't. Model::create(array $attributes = []) is using method fill(array $attributes = []), which, we may say, filter out all guarded attributes, so they will not be assigned. So in point of creation tnant_id will be null.
I come up with two ways of doing this:
A
create a new model instance
set your attribute
save (persist) it to dabase;
So:
$model = new Model;
$model->tnant_id = 123;
$model->save();
B
This is more likely update than create, but, might be useful for you.
Change your DB schema to allow null values for your attribute or put default value.
create model using Model::create()
set attribute & update.
So:
Assuming you are using migrations, in your migration file use:
Schema::create(..
$table->integer('trant_id')->nullable();
//OR
$table->integer('trant_id')->default(0);
...);
Note: It's hard to say which one is more suitable for you use-case, but I see your attribute is called trant_id, which is some form of relation I guess, so I suggest you to take look at Eloquent's relationship, which might be a better answer.

Laravel Eloquent combine Model::forceCreate and Model::firstOrCreate

With Laravel & Eloquent, I'd like to :
Create a model, unless it already exists into the database (like Model::firstOrCreate allows)
At the same time, pass it a few attributes, including some which are not listed in the $fillable array of the model (like Model::forceCreate allows).
But how do I combine the capacities of firstOrCreate and forceCreate? Apparently, Model::forceFirstOrCreate doesn't exist!
Use the unguarded method:
$model = Model::unguarded(function() {
return Model::firstOrCreate($attributes);
});

laravel mongodb does not save

The documentation doesn't go into much detail about saving data to mongodb.
I've installed a fresh install of laravel and set the up the mongo connections as in the docs, installed mongodb itself.
Created a model
use Jenssegers\Mongodb\Model as Eloquent;
class Notifications extends Eloquent {
protected $connection = 'mongodb';
protected $collection = 'notifications';
public static function foo()
{
return 'test returning from model';
}
}
And create a simple route to test
Route::get('notifiction' , function(){
$notifiction = new Notifications();
$arr = array('name' => 'John Doe');
$notifiction->save($arr);
});
But when I run localhost/mongo/public/notifiction I get Whoops, looks like something went wrong. I'm not sure what else needs doing to save information to mongodb through laravel?
This error is most likely to do with mass assignment. That is laravel treats every thing as unsafe before saving it to database. Thus we have to whitelist the fields we are trying to save.
The way we do this is in model. Lets say you are trying to save data in Users table using USER model. First open app/models/user.php and add following line:
class User extends Eloquent {
protected $fillable = ['name'];
}
Above, in fillable we are listing name as we want to save name from controller (if you have any additional data fill in the array). Now we can save data from controller.
Eg: User::create(array('name' => 'John')); will save name in Users collection. Please note the name of collection will be the name of the model unless specified otherwise.
[If this does not solve your problem, enable debug by going to app/config/app.php and setting debug =true. Find the error and try searching.]
You need not to do like model for SQL.
You try model like this
class User extends Moloquent {
protected $connection = 'mongodb';
protected $collection = 'collection1';
protected $fillable = ['_id','userName','passwd'];
}
You can try this to insert
DB::connection('mongodb')->collection('collection1')
->insert(array(
'_id' => 'H12345',
'userName' => 'Nithil',
'passwd' => 'qwoeuig'));
Using Moloquent is more convenient in using multiple DBS. For using Moloquent, you may register an alias for the MongoDB model by adding the following to the alias array in app/config/app.php:
'Moloquent' => 'Jenssegers\Mongodb\Model',
This will allow you to use the registered alias like:
class MyModel extends Moloquent {}
As OP has mentioned the error was due to
Did not installed the MongoDB PHP Library
Apart from that, to do mass assignment in Laravel, the fields should either be "white listed" or "black listed"
To whitelist the field(s) add
// name, age, username and email could be mass assigned
protected $fillable = ['name', 'age', 'username', 'email'];
To blacklist the field(s) add
// except _id everything could be mass assigned
protected $guarded = ['_id'];
to your model file

Categories