I'm trying to get roles and permissions to work properly, but I can't seem to get this right. I get an error while seeding the database:
[BadMethodCallException]
Call to undefined method Illuminate\Database\Query\Builder::attachRole()
I assume I'm doing something wrong, but I can't see what it would be.
use Bican\Roles;
use Bican\Roles\Models\Role;
use Illuminate\Database\Seeder;
use Illuminate\Foundation\Auth\User;
class UserTableSeeder extends Seeder
{
public function run()
{
// Create admin
$adminRole = Role::where('name', '=', 'Admin')->first();
$user = User::create([
'name' => 'Admin',
'email' => 'email#domain.com',
'password' => bcrypt('Password99')
]);
$user -> attachRole($adminRole);
}
}
What I try to use is this: https://github.com/romanbican/roles
I followed the installation instructions and all went well until I was going to test it. The roles table seeder runs fine, and I can see the roles in the database. But I cant assing roles to users.
What am I doing wrong?
Just found out... I'm using use Illuminate\Foundation\Auth\User; when I need to use use App\User; Working now.
Related
I'm using VueJS and Laravel for an application I'm developing. I've tried to search here for an answer, but I haven't found anything that works. Most of the times, it's because there's really nothing to return, but I've tried to debug my query quite a bit, and I don't understand why I keep getting a null.
So I'm trying to get information about the student who's logged in, so I'm doing an axios get on a route that executes the following:
public function getByUserId($id) {
//$student = $this->studentRepo->findByUserId($id);
$student = Student::where('user_id', $id)->first();
$inscription = Inscription::where('student_id', $student->id)->first();
$student->careers;
$res = $inscription ? new InscriptionResource($inscription) : '';
return response()->json([
'student' => new StudentResource($student),
'inscription' => $res,
]);
}
The thing is, it doesn't find the student with that user_id. I've checked if the user_id (param: $id) is getting there as expected and it is. I've also tried to get the query via ->toSql() and copy pasted the query on the database to test it and I do get the student I'm trying to search for. Thing is, it's not finding it in Laravel for some reason, I'm not sure why.
My student table does have the attribute "user_id", I've checked.
Student file:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Student extends Model {
use SoftDeletes;
protected $dates = ['deleted_at'];
public function charges() {
return $this->hasMany('App\Models\Payment');
}
}
Add the related column in the relation function
public function charges() {
return $this->hasMany('App\Models\Payment', '');
}
I have a regular User model. The system works fine when I use it. But now I am trying to create unit tests in the PHPUnit that integrated with Laravel.
I have a factory that creates a user:
$factory->define(App\User::class, function (Faker\Generator $faker) {
return [
'id' => $faker->randomNumber(9),
'email' => $faker->safeEmail,
'first_name' => $faker->firstNameMale,
'last_name' => $faker->lastName,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
I changed the User to have integer ID as the primary key but it not defined as auto-increment.
So the factory create random number for the ID.
Also I have created the simple test:
public function test_id_is_visible() {
$user = factory(App\User::class)->create();
$this->actingAs($user);
$this->visit('/userprofile');
$this->see($user->id);
}
That test always fails, but it seems to be OK when I navigate to the page manually.
I have noticed that in the test the $user->id is always 0. Even it can't be 0 in the factory. I checked and Laravel insert the user correctly to the database and it have correct ID, but in the code I always get 0.
What can I do to get the correct value of the ID?
EDIT
Now I see that if I changes $user = factory(App\User::class)->create(); to $user = factory(App\User::class)->make(); the user instance holds a correct ID. But why create clears the ID?
Update for Laravel 5.8+ Make sure to set
public $incrementing = false;
on your model.
The problem happened because the ID is not defined as auto-increment.
More information you can found in:
https://stackoverflow.com/a/31350800/1725836
Even the question is for Laravel 4 it is still relevant for Laravel 5.2.
You can write your tests like this:
$users = factory(User::class, 5)->make();
$users->each(function ($item, $key) {
$item->id = ++$key;
});
Now each user will have an id, without the need to persist the models to database (using create() instead of make()).
public function test_id_is_visible() {
$user = factory(App\User::class)->make();
$user->id = 7;
$this->actingAs($user);
$this->visit('/userprofile');
$this->see($user->id);
}
I am following the tutorial in "Laravel 5 Essentials." When I try to seed my database with the command
php artisan db:seed
I receive the error
[ReflectionException]
Class BreedsTableSeeder does not exist
The code for BreedsTableSeeder is defined below:
<?
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class BreedsTableSeeder extends Seeder {
public function run()
{
DB:table('breeds')->insert([
['id' => 1, 'name' => "Domestic"],
['id' => 2, 'name' => "Persian"],
['id' => 3, 'name' => "Siamese"],
['id' => 4, 'name' => "Abyssinian"],
]);
}
}
The DatabaseSeeder is defined as such:
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Model::unguard();
// $this->call(UserTableSeeder::class);
$this->call('BreedsTableSeeder');
}
}
1
I noticed that "DB" has a different color when I load sample code in Sublime, which makes me suspect that this has something to do with the DB namespace. Because I am new to Laravel, I am not sure where DB should be defined.
I also tried executing
composer dump-autoload
but that did not work. Does anyone know how to fix this problem? Thanks!
Try:
php artisan make:seeder BreedsTableSeeder
Details can be found - Laravel seeding
A couple things :
It sounds like your seeder class didn't get added to the classmap for some reason. The place to check is the /vendor/composer/autoload_classmap.php file. If you see your class in there, it should work. If you don't, then a name change or something else went wrong at some point and you may need to add it manually.
You will need to add the namespace for the DB class. It should be :
use Illuminate\Support\Facades\DB;
You just need to add use Illuminate\Support\Facades\DB; to the top of your BreedsTableSeeder file.
I have a Seeder for different models and one of them is giving me the following error when I try to artisan db:seed
PHP Fatal error: Call to undefined method Illuminate\Events\Dispatcher::create() in C:\www\site\bootstrap\compiled.php on line 3155
Here's Event.php, the model that seems to cause the problem:
<?php
class Event extends Eloquent {
protected $fillable = array('name', 'played_on');
protected $table = 'events';
// RELATIONSHIPS ----------------------------
// Event has many Decks
public function decks() {
return $this->belongsToMany('Deck', 'decks_events', 'event_id', 'deck_id');
}
}
Note: I added the protected $table = 'events' to try and see if this was causing the problem, I don't think it's required. Here is part of the Seeder. The Deck part works fine (in fact, I do see the 'Added some cards to some decks' message because it crashes)
// Decks
$deck_1 = Deck::create(array(
'meta' => 'U/W Control',
'player' => 'Cookie Monster'
));
$deck_2 = Deck::create(array(
'meta' => 'RDW',
'player' => 'Suzy Waterbottle'
));
// All 3 cards in Deck 1
$card_1->decks()->attach($deck_1->id);
$card_2->decks()->attach($deck_1->id);
$card_3->decks()->attach($deck_1->id);
// 2 cards in Deck 2
$card_1->decks()->attach($deck_2->id);
$card_2->decks()->attach($deck_2->id);
$this->command->info('Added some cards to some decks');
// Events
$event_1 = Event::create(array(
'name' => 'Super Duper Tourney',
'played_on' => '07/05/2014'
));
$deck_1->events()->attach($event_1->id);
$deck_2->events()->attach($event_1->id);
$this->command->info('Added decks to the event');
This leads me to believe that something wrong happens on the $event_1 = Event::create line but I can't figure out what as it looks exactly like the code used for $deck_1... and $deck_2...
Event is a "reserved" word in Laravel. You may have to change it or namespace your class.
So, instead of your Event model class, it is using Laravel Event, which is Illuminate\Events\Dispatcher.
It is actually an Alias we have on app/config/app.php.
Namespacing it:
<?php namespace App;
use Eloquent;
class Event extends Eloquent {
...
}
Using it namespaced:
<?php
use App\Event;
class Whatever {
$event_1 = Event::create(array(
'name' => 'Super Duper Tourney',
'played_on' => '07/05/2014'
));
}
You may need to
composer dumpautoload
To refresh your autoloaded namespaces and classes.
I am a Laravel newbie. I want to seed my database. When I run the seed command I get an exception
[Illuminate\Database\Eloquent\MassAssignmentException]
username
db:seed [--class[="..."]] [--database[="..."]]
What am I doing wrong. The command I use is:
php artisan db:seed --class="UsersTableSeeder"
My seed class is as follows:
class UsersTableSeeder extends Seeder {
public function run()
{
User::truncate();
User::create([
'username' => 'PaulSheer',
'email' => 'psheer#rute.co.za',
'password' => '45678'
]);
User::create([
'username' => 'Stevo',
'email' => 'steve#rute.co.za',
'password' => '45678'
]);
}
}
Read this section of Laravel doc : http://laravel.com/docs/eloquent#mass-assignment
Laravel provides by default a protection against mass assignment security issues. That's why you have to manually define which fields could be "mass assigned" :
class User extends Model
{
protected $fillable = ['username', 'email', 'password'];
}
Warning : be careful when you allow the mass assignment of critical fields like password or role. It could lead to a security issue because users could be able to update this fields values when you don't want to.
I am using Laravel 4.2.
the error you are seeing
[Illuminate\Database\Eloquent\MassAssignmentException]
username
indeed is because the database is protected from filling en masse, which is what you are doing when you are executing a seeder. However, in my opinion, it's not necessary (and might be insecure) to declare which fields should be fillable in your model if you only need to execute a seeder.
In your seeding folder you have the DatabaseSeeder class:
class DatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Eloquent::unguard();
//$this->call('UserTableSeeder');
}
}
This class acts as a facade, listing all the seeders that need to be executed. If you call the UsersTableSeeder seeder manually through artisan, like you did with the php artisan db:seed --class="UsersTableSeeder" command, you bypass this DatabaseSeeder class.
In this DatabaseSeeder class the command Eloquent::unguard(); allows temporary mass assignment on all tables, which is exactly what you need when you are seeding a database. This unguard method is only executed when you run the php aristan db:seed command, hence it being temporary as opposed to making the fields fillable in your model (as stated in the accepted and other answers).
All you need to do is add the $this->call('UsersTableSeeder'); to the run method in the DatabaseSeeder class and run php aristan db:seed in your CLI which by default will execute DatabaseSeeder.
Also note that you are using a plural classname Users, while Laraval uses the the singular form User. If you decide to change your class to the conventional singular form, you can simply uncomment the //$this->call('UserTableSeeder'); which has already been assigned but commented out by default in the DatabaseSeeder class.
To make all fields fillable, just declare on your class:
protected $guarded = array();
This will enable you to call fill method without declare each field.
Just add Eloquent::unguard(); in the top of the run method when you do a seed, no need to create an $fillable array in all the models you have to seed.
Normally this is already specified in the DatabaseSeeder class. However because you're calling the UsersTableSeeder directly:
php artisan db:seed --class="UsersTableSeeder"
Eloquent::unguard(); isn't being called and gives the error.
I used this and have no problem:
protected $guarded=[];
I was getting the MassAssignmentException when I have extends my model like this.
class Upload extends Eloquent {
}
I was trying to insert array like this
Upload::create($array);//$array was data to insert.
Issue has been resolve when I created Upload Model as
class Upload extends Eloquent {
protected $guarded = array(); // Important
}
Reference https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670
User proper model in your controller file.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
if you have table and fields on database you can simply use this command :
php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE
This is not a good way when you want to seeding database.
Use faker instead of hard coding, and before all this maybe it's better to truncate tables.
Consider this example :
// Truncate table.
DB::table('users')->truncate();
// Create an instance of faker.
$faker = Faker::create();
// define an array for fake data.
$users = [];
// Make an array of 500 users with faker.
foreach (range(1, 500) as $index)
{
$users[] = [
'group_id' => rand(1, 3),
'name' => $faker->name,
'company' => $faker->company,
'email' => $faker->email,
'phone' => $faker->phoneNumber,
'address' => "{$faker->streetName} {$faker->postCode} {$faker->city}",
'about' => $faker->sentence($nbWords = 20, $variableNbWords = true),
'created_at' => new DateTime,
'updated_at' => new DateTime,
];
}
// Insert into database.
DB::table('users')->insert($users);
Use the fillable to tell laravel which fields can be filled using an array.
By default, Laravel does not allow database fields to be updated via an array
Protected $fillable=array('Fields you want to fill using array');
The opposite of fillable is guardable.
If you use the OOP method of inserting, you don't need to worry about mass-action/fillable properties:
$user = new User;
$user->username = 'Stevo';
$user->email = 'steve#rute.co.za';
$user->password = '45678';
$user->save();