Hello everyone who's trying to help,
im trying to create the factory file to seeding my database and i have a question how can i insert a foreign key from a table already seeded ?
and the factory code is to have all in same file? any good pratice to this ?
Files
Model User
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $table = 'user'; //name of the table in database
protected $primaryKey = 'Id'; //Primary Key of the table
/**
* Relations between tables
*/
public function GetLoginInfo()
{
return $this->hasMany('App\Models\LoginInfo', 'UserId');
}
public function getStatus()
{
return $this->belongsTo('App\Models\AccountStatus');
}
}
Model Account status
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AccountStatus extends Model
{
protected $table = 'account_status'; //name of the table in database
protected $primaryKey = 'Id'; //primary Key of the table
public $timestamps = false; //true if this table have timestaps
/**
* Relations between tables
*/
public function GetUsers()
{
return $this->hasMany('App\Models\Users', 'StatusId');
}
}
factory file:
<?php
/** #var \Illuminate\Database\Eloquent\Factory $factory */
//Factory for Account Status table
$factory->define(App\Models\AccountStatus::class, function (Faker\Generator $faker) {
return [
'Description' => $faker->word,
];
});
//Factory for user table
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => Factory(App\Models\AccountStatus::class)->create()->id,
];
});
This is what im trying to do as you can see : Factory(App\Models\AccountStatus::class)->create()->id but don't work
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => factory(App\Models\AccountStatus::class)->create()->id,
];
});
i see an uppercase F in factory..
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
$accountStatus = factory(App\Models\AccountStatus::class)->create()
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => $accountStatus->id,
];
});
Edit (Improvement)
If you have one model that depend on another model. you can do it this way, using a callback function to create with the related.
Like this
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => function () {
return factory(App\Models\AccountStatus::class)->create()->id;
}
];
});
One thing you need to keep in mind is that this will go to an endless loop if the related(Status Model) has a model that depends on the parent(User Model).
Related
I get a 404 error when I try to insert user's details into multiple tables during registration
my user model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
use Notifiable;
use HasRoles;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username','accno', 'email', 'password', 'role', 'status', 'activation_code'
];
protected $guarded = [];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
// a mutator for the email attribute of our model with email validation check and check to avoid duplicate email entries.
protected $table = 'users';
public $timestamps = false;
public $incrementing = false;
public function setEmailAttribute($email)
{
// Ensure valid email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \Exception("Invalid email address.");
}
// Ensure email does not exist
elseif (static::whereEmail($email)->count() > 0) {
throw new \Exception("Email already exists.");
}
$this->attributes['email'] = $email;
}
public function setPasswordAttribute($password)
{
$this->attributes['password'] = Hash::make($password);
}
public function profiles()
{
return $this->hasOne(profiles::class);
}
public function accounts()
{
return $this->hasOne(accounts::class);
}
public function transactions()
{
return $this->hasMany(transactions::class);
}
}
I try refactoring by separating my validation code from my logic using RegisterUserTrait
<?php
namespace App\Traits;
use App\User;
use App\Profile;
use App\Account;
use Keygen;
trait RegisterUser
{
public function registerUser($fields)
{
$user = User::create([
'username' => $fields->username,
'accno' => $this->generateAccountNumber(),
'email' => $fields->email,
'password' => $fields->password = bcrypt(request('password')),
'roles' => $fields->roles,
'activation_code' => $this->generateToken()
]);
Profile::create([
'accno' => $user->accno,
'username' => $user->username,
'acc_type' => $fields->acc_type,
'firstname' => $fields->firstname,
'lastname' => $fields->lastname,
'nationality' => $fields->nationality,
'occupation' => $fields->occupation,
'address' => $fields->address,
'city' => $fields->city,
'state' => $fields->state,
'zipcode' => $fields->zipcode,
'phoneno' => $fields->phoneno,
'dob' => $fields->dob,
'gender' => $fields->gender,
'martial_status' => $fields->martial_status,
'user_image' => $fields->user_image,
]);
Account::create([
'accno' => $user->accno,
'username' => $user->username,
]);
return $user;
}
then storing the data using my registrationController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use App\Http\Requests\RegistrationRequest;
use App\Traits\RegisterUser;
class RegistrationController extends Controller
{
use RegisterUser;
public function show()
{
return view('auth/register');
}
public function register(RegistrationRequest $requestFields)
{
//calling the registerUser method inside RegisterUser trait.
$user = $this->registerUser($requestFields);
return redirect('/login');
}
}
but when I register the user, the data is only saved in the create_user_table and return a 404 page not found error. How can I save the data to the selected table and redirect to the login page?
As fa as i can see this is not true for foreign key relations in User Model
public function profiles()
{
return $this->hasOne(profiles::class);
}
public function accounts()
{
return $this->hasOne(accounts::class);
}
public function transactions()
{
return $this->hasMany(transactions::class);
}
it should be as follows;
public function profiles()
{
return $this->hasOne(Profile::class);
}
public function accounts()
{
return $this->hasOne(Account::class);
}
public function transactions()
{
return $this->hasMany(Transaction::class);
}
Try this
public function registerUser($fields)
{
$user = User::create([
'username' => $fields->username,
'accno' => $this->generateAccountNumber(),
'email' => $fields->email,
'password' => $fields->password = bcrypt(request('password')),
'roles' => $fields->roles,
'activation_code' => $this->generateToken()
]);
$user->userprofile =Profile::create([
'accno' => $user->accno,
'username' => $user->username,
'acc_type' => $fields->acc_type,
'firstname' => $fields->firstname,
'lastname' => $fields->lastname,
'nationality' => $fields->nationality,
'occupation' => $fields->occupation,
'address' => $fields->address,
'city' => $fields->city,
'state' => $fields->state,
'zipcode' => $fields->zipcode,
'phoneno' => $fields->phoneno,
'dob' => $fields->dob,
'gender' => $fields->gender,
'martial_status' => $fields->martial_status,
'user_image' => $fields->user_image,
]);
$user->useraccount = Account::create([
'accno' => $user->accno,
'username' => $user->username,
]);
return $user;
}
If you are using a voyager package then there is a log file where you will find error messages that can help you understand the exact problem .
the log interface existe in voyager admin panel in :
Tools => Compass => Logs
look at this image :
Try this in your User model
protected static function boot()
{
protected static function boot()
parent::boot();
static::created(function ($user){
$user->profiles()->create([
'accno' => $user->accno,
'username' => $user->username,
.... => ....
]);
$user->accounts()->create([
'accno' => $user->accno,
'username' => $user->username,
]);
});
}
An error 404 is often a problem with a route.
As requested by Christos Lytras in a comment, we need to see your routes/web.php and the output of php artisan route:list to verify.
I believe the redirect in your registrationController is not pointing to a valid url:
return redirect('/login');
Without seeing your routes I can't say for sure but if your login route name is defined, you can do:
return redirect()->route('login');
Please share your routes file to confirm.
create() method is used for mass assignment. you will need to specify either a fillable or guarded attribute on the model. So check the fillable attribute on Profile and Account Model.
I am running Laravel 5.2, on Windows 8.1 using XAMPP with php 7.2, and I am trying to register a user using laravel auth register form with sqlite database. However when I try insert new record to table users I got error.
SQLSTATE[HY000]: General error: 1 no such table: user
When I migrate database it creates users table. But when I try to insert new record in users table with register form it tries to access user table. So I created user table in database it works fine but the record is inserted in users table and not in user table.
Migration
public function up(){
Schema::create('users', function (Blueprint $table) {
$table->increments('user_id');
$table->string('name');
$table->string('role');
$table->string('username');
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down(){
Schema::drop('users');
}
User model
class User extends Authenticatable{
protected $primaryKey = 'user_id';
protected $fillable = [
'name', 'role', 'username', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
}
AuthController
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectTo = '/';
protected $username = 'username';
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'role' => 'required|max:7',
'username' => 'required|unique:user',
'password' => 'required|min:6|confirmed',
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'role' => $data['role'],
'username' =>$data['username'],
'password' => bcrypt($data['password']),
]);
}
}
thanks for help and sorry for bad english.
Your issue is in the validation:
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'role' => 'required|max:7',
'username' => 'required|unique:user',
'password' => 'required|min:6|confirmed',
]);
}
You are checking if the username is unique in user not users, try this:
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'role' => 'required|max:7',
'username' => 'required|unique:users,username',
'password' => 'required|min:6|confirmed',
]);
}
Also you will likely want to add a unique constraint on the migration.
In your users model add public $table = 'users' | public $table = 'user'
Please refer to this:
https://laravel.com/docs/5.6/eloquent#eloquent-model-conventions
If you have a model User, then you must have the table as "users" not "user" in your database.
I had a similar error. It was due to
Schema::create('tasks', function (Blueprint $table) {
$table->foreignId('owner_id')->nullable()->constrained('user')->index();
instead of (note the s in users)
$table->foreignId('owner_id')->nullable()->constrained('users')->index();
This could be because you tried using a different name in your model fillable .Try to make sure that the names are identical for example you can not use user_id in your migration database table then you use users_id in your user model
There is a a single form which takes in details and save it to 4 different tables in db. Project, Events, Donation and Opportunities. Project has many Events, many Donation and many Opportunities. I want to use the project id in other tables as well. but when I save the Form the details are stored in each 4 tables but the project is not been taken for the other 3 tables Events, Donation and Opportunity. Its value is 0. How to take that particular project id(auto-increment) in all other three tables.
My ProjectController is like this:
class ProjectController extends Controller
{
public function getProject()
{
return view ('other.project');
}
public function postProject(Request $request)
{
$this->validate($request, [
'ptitle' => 'required|max:200',
'pdescription' => 'required',
'etitle' => 'required|max:200',
'edetails' => 'required',
'dtotal' => 'required',
'oposition' => 'required|max:100',
'odescription' => 'required',
]);
Project::create([
'ptitle' => $request->input('ptitle'),
'pdescription' => $request->input('pdescription'),
'pduration' => $request->input('pduration'),
'psdate' => $request->input('psdate'),
'pedate' => $request->input('pedate'),
'pcategory' => $request->input('pcategory'),
'pimage' => $request->input('pimage'),
]);
Event::create([
'pro_id' => $request->input('pid'),
'etitle' => $request->input('etitle'),
'pdetails' => $request->input('pdetails'),
'edate' => $request->input('edate'),
'etime' => $request->input('etime'),
'elocation' => $request->input('elocation'),
'eimage' => $request->input('eimage'),
]);
Donation::create([
'pro_id' => $request->input('pid'),
'dtotal' => $request->input('dtotal'),
'dinhand' => $request->input('dinhand'),
'dbankaccount' => $request->input('dbankaccount'),
]);
Opportunity::create([
'pro_id' => $request->input('pid'),
'oposition' => $request->input('oposition'),
'odescription' => $request->input('odescription'),
'olocation' => $request->input('olocation'),
'odeadline' => $request->input('odeadline'),
]);
return redirect()
->route('home')
->with('info', 'Your project has been created.');
}
My Project Model:
class Project extends Model
{
use Notifiable;
protected $fillable = [
'ptitle',
'pdescription',
'pduration',
'psdate',
'pedate',
'pcategory',
'pimage',
];
public function events()
{
return $this->hasMany('Ngovol\Models\Event', 'pro_id');
}
public function donations()
{
return $this->hasMany('Ngovol\Models\Donation', 'pro_id');
}
public function opportunities()
{
return $this->hasMany('Ngovol\Models\Event', 'pro_id');
}
protected $hidden = [
];
}
Event Model:
class Event extends Model
{
use Notifiable;
protected $table = 'events';
protected $fillable = [
'pro_id',
'etitle',
'edetails',
'edate',
'etime',
'elocation',
'eimage',
];
public function projects()
{
return $this->belongsTo('Ngovol\Models\Project', 'pro_id');
}
}
Donation Model:
class Donation extends Model
{
use Notifiable;
protected $fillable = [
'pro_id',
'dtotal',
'dinhand',
'drequired',
'dbankaccount',
];
protected $hidden = [
];
public function projects()
{
return $this->belongsTo('Ngovol\Models\Project', 'pro_id');
}
}
Opportunity Model:
class Opportunity extends Model
{
use Notifiable;
protected $fillable = [
'pro_id',
'oposition',
'odescription',
'olocation',
'odeadline',
];
protected $hidden = [
];
public function projects()
{
return $this->belongsTo('Ngovol\Models\Project', 'pro_id');
}
}
Better try following code
$project = Project::create( $request->only(['ptitle', 'pdescription', 'pduration', 'psdate', 'pedate', 'pcategory', 'pimage']));
$project->events()->create( $request->only(['etitle', 'pdetails', 'edate', 'etime', 'elocation', 'eimage']));
$project->donations()->create($request->only(['dtotal', 'dinhand', 'dbankaccount']));
$project->opportunities()->create($request->only(['oposition','odescription','olocation','odeadline']));
I'm trying to seed a database using some model factories but I'm getting error call to member function create() on a non-object
Below are my model factories:
$factory->define(App\Organisation::class, function ($faker) {
return [
'name' => $faker->company,
];
});
$factory->define(App\Department::class, function ($faker) {
return [
'name' => $faker->catchPhrase,
'organisation_id' => factory(App\Organisation::class)->make()->id,
];
});
$factory->define(App\User::class, function ($faker) {
return [
'email' => $faker->email,
'password' => str_random(10),
'organisation_id' => factory(App\Organisation::class)->make()->id,
'remember_token' => str_random(10),
];
});
In my seeder I'm using the following to create 2 organizations and a associate a user and a department to each organization and then to make a user the manager of that department:
factory(App\Organisation::class, 2)
->create()
->each(function ($o)
{
$user = $o->users()->save(factory(App\User::class)->make());
$department = $o->departments()->save(factory(App\Department::class)->make());
$department->managedDepartment()->create([
'organisation_id' => $o->id,
'manager_id' => $user->id,
]);
});
However I'm getting fatalerrorexception call to member function create() on a non-object
I thought $department is an object?
My department model is as follows:
class Department extends Model
{
protected $fillable = ['name','organisation_id'];
public function organisation()
{
return $this->belongsTo('App\Organisation');
}
/* a department is managed by a user */
public function managedDepartment()
{
$this->hasOne('App\ManagedDepartment');
}
}
And my managedDepartment model is as follows:
class ManagedDepartment extends Model
{
protected $table = 'managed_departments';
protected $fillable = ['organisation_id', 'department_id', 'manager_id',];
public function department()
{
$this->belongsTo('App\Department');
}
public function manager()
{
return $this->belongsTo('App\User');
}
}
Can anyone help?
Try to return your relation
public function department()
{
return $this->belongsTo('App\Department');
}
And here
/* a department is managed by a user */
public function managedDepartment()
{
return $this->hasOne('App\ManagedDepartment');
}
I think it will resolve your problem.
Firstly, do not make foreign keys fillable!
Secondly, where is your organisation function in ManagedDepartment? You should create one, otherwise the following will not work, because association is not possible.
Thirdly, I think you should change make() to create() in the following
$factory->define(App\Organisation::class, function ($faker) {
return [
'name' => $faker->company,
];
});
$factory->define(App\Department::class, function ($faker) {
return [
'name' => $faker->catchPhrase,
'organisation_id' => factory(App\Organisation::class)->create()->id,
];
});
$factory->define(App\User::class, function ($faker) {
return [
'email' => $faker->email,
'password' => str_random(10),
'organisation_id' => factory(App\Organisation::class)->create()->id,
'remember_token' => str_random(10),
];
});
Furthermore:
factory(App\Organisation::class, 2)
->create()
->each(function ($o)
{
$user = factory(App\User::class)->create();
$o->users()->attach($user->id);
$department = factory(App\Department::class)->create();
$o->departments()->attach($department);
$managedDep = new ManagedDepartment();
$managedDep->associate($o);
$managedDep->associate($user);
$managedDep->associate($department);
$managedDep->save();
});
I am using Laravel 4.2 and I'm trying to auth my own model (I don't use User model).
The problem appears when pass the mail and password, then I use the method Auth::attempt and enters to else (that it corresponds to the error)
Usuario Controller
class UsuarioController extends BaseController{
function doLogin(){
$userdata = array(
'Correo' => Input::get('correo'),
'Contrasena' => Input::get('contrasena')
);
if(Auth::attempt($userdata)){
echo 'SUCCESS!';
}else{
echo 'Error!';
}
} ...
Usuario Model
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Usuario extends Eloquent implements UserInterface, RemindableInterface {
protected $table = 'Usuario';
protected $primaryKey = 'idUsuario';
protected $fillable = array(
'Nombre',
'Apellido',
'Rol',
'Correo',
'Contarsena',
'Cumpleanos',
'Foto',
'Pais',
'Comuna',
'Profesion_idProfesion',
'Institucion_idInstitucion',
'remember_token'
);
function profesion(){
return $this->belongsTo('Profesion', 'idProfesion');
}
public function getPasswordAttribute()
{
return $this->Contrasena;
}
public function setPasswordAttribute($Contrasena)
{
$this->Contrasena= $Contrasena;
}
public function getReminderEmail()
{
return $this->Correo;
}
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword() {
return $this->Contrasena;
}
}
Auth.php
return array(
'driver' => 'eloquent', //database or eloquent
'model' => 'Usuario',
'table' => 'Usuario',
'username' => 'Correo',
'password' => 'Contrasena',
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
Usuario Table
The application never crash but in the If Condition always enter to the ''else'' returns Error!
You have a typo in your fillable array:
protected $fillable = array(
'Nombre',
'Apellido',
'Rol',
'Correo',
'Contarsena',
'Cumpleanos',
'Foto',
'Pais',
'Comuna',
'Profesion_idProfesion',
'Institucion_idInstitucion',
'remember_token'
);
Contarsena should be Contrasena
And your auth array should contain a email and password key:
$userdata = array(
'correo' => Input::get('correo'),
'password' => Input::get('contrasena')
);
try
dd(DB::getQueryLog());
to get the the SQL executed. That makes troubleshooting easier.
My guess is that there's no 'password' field, which the attempt method will automatically hash