Use one Laravel migrations table per database - php

I work in a project that uses multiple databases. It seems like Laravel only uses the migrations-table in the database that is set as default. I would like one migrations table per database that logs the migrations that have been done to that specific database. Is this possible?
I have defined the databases in the config like this:
'connections' => [
'db1' => array(
'driver' => 'mysql',
'host' => 'db1.host',
'database' => 'db1',
'username' => 'username',
'password' => 'password',
),
'db2' => [
'driver' => 'mysql',
'host' => 'db2.host',
'database' => 'db2',
'username' => 'username',
'password' => 'password',
]
],
I also made the first database (db1) the default one
'default' => 'db1'
I install the migrations table on both databases
artisan migrate:install --database=db1
artisan migrate:install --database=db2
After that i proceed to create a couple of database specifc migrations
Create table test1 in db1 database:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTest1Table extends Migration
{
public function up()
{
Schema::connection('db1')->create('test1', function(Blueprint $table)
{
$table->increments('id')->unsigned();
});
}
public function down()
{
Schema::connection('db1')->drop('test1');
}
}
Create table test2 in db2 database:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTest2Table extends Migration
{
public function up()
{
Schema::connection('db2')->create('test2', function(Blueprint $table)
{
$table->increments('id')->unsigned();
});
}
public function down()
{
Schema::connection('db2')->drop('test2');
}
}
I now run the migrations
artisan migrate
Expected outcome
db1.migrations
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
| create_test1_table_in_db1 | 1 |
+-----------------------------+-------+
db2.migrations
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
| create_test2_table_in_db2 | 1 |
+-----------------------------+-------+
Actual outcome
db1.migrations
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
| create_test1_table_in_db1 | 1 |
| create_test2_table_in_db2 | 1 |
+-----------------------------+-------+
db2.migrations
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
Empty set

Article on usage of multiple database usage in Laravel -
https://stackcoder.in/posts/laravel-7x-multiple-database-connections-migrations-relationships-querying
Use the --database parameter with the migrate command and store the migrations for each database in separate directories.
You could have separate directories in app/database/migrations for each of your database (in your case db1 and db2) and store the appropriate migrations in each directory. Then you could run the migrations like this:
artisan migrate --database="db1" --path="app/database/migrations/db1"
artisan migrate --database="db2" --path="app/database/migrations/db2"
This way your migrations table will be independent for each database.
If you want to go the extra mile and automate the process you could create your custom command that will run all the migrations at once. You can create the command like this (use make:console for Laravel 5.0 up to 5.2 or make:command for Laravel 5.2+):
artisan command:make MigrateAllCommand --command=migrate:all
This will create a new file app/commands/MigrateAllCommand.php. Your command's fire method would look something like this:
public function fire()
{
foreach (Config::get('database.connections') as $name => $details)
{
$this->info('Running migration for "' . $name . '"');
$this->call('migrate', array('--database' => $name, '--path' => 'app/database/migrations/' . $name));
}
}
This will work provided the name of the database configuration key is the same as the migration directory name. You can then just call it like this:
artisan migrate:all
You can check the Laravel Command Docs for more info.

Related

Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable

So I am trying to authenticate an unusual login model, Teachers, which uses Employee ID and Password as the login parameters. The database is also not the regular Users but Teachers. I am getting the following error.
**
Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Teacher given, called in C:\xampp\htdocs\schoolcms\vendor\laravel\framework\src\Illuminate\Auth\SessionGuard.php on line 385
**
This is my Teacher model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Teacher extends Model
{
//
}
This is my TeacherController part where the login attempt is being made
<?php
namespace App\Http\Controllers;
use App\Teacher;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class TeacherController extends Controller
{
public function login()
{
$teachers = Teacher::all();
return view('index', [ 'layout'=>'login']);
}
/**
* authenticate login credentials.
*/
public function authenticate(Request $request)
{
$userCredentials = $request->only('EmployeeID', 'Password');
// check user using auth function
if (Auth::attempt($userCredentials)) {
return view('student', [ 'layout'=>'index']);
}
else {
return view('index', [ 'layout'=>'master']);
}
/*return view('student', ['students'=>$teachers, 'layout'=>'register']);*/
}
}
This is my config/auth.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'teachers',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
/*A guard key has an array for it’s value and that array has two key-value pairs. First driver and second is provider.*/
'web' => [
'driver' => 'session',
'provider' => 'teachers',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
/*Providers are used to define how our users will be retrieved and how the user data with be stored after authentication.
/We are using eloquent so we will define the model that will be used for authentication.
*/
'teachers' => [
'driver' => 'eloquent',
'model' => App\Teacher::class,
],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'teachers' => [
'provider' => 'teachers',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
The approach could be easier by customizing in the Controller.
public function authenticate(Request $request)
{
$userCredentials = $request->only('EmployeeID', 'Password');
// check user using auth function
if ($teachers=Teacher::where($userCredentials)->first()) {
auth()->login($teachers);
// redirect to the intended view
}
else {
// redirect to the view on failure to authenticate with a failure message
}
}

No migrations were found

I am creating migrations in codeigniter. But I get an error saying that migrations are not found. I consulted official codeigniter docs. But in google, I couldn't find this error.
I created migrations folder and added following file.
001_Create_users.php
<? php
/**
* Description of 001_create_users
*
* #author Isuru
*/
class Migration_Create_users extends CI_Migration {
public
function up() {
$this - > dbforge - > add_field('id');
$this - > dbforge - > add_field(array(
'id' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => TRUE,
'auto_increment' => TRUE
),
'email' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
'password' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
'name' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
));
//$this->dbforge->add_key('id', TRUE);
$this - > dbforge - > create_table('users');
}
public function down() {
$this - > dbforge - > drop_table('users');
}
}
This is the migration.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
|--------------------------------------------------------------------------
| Enable/Disable Migrations
|--------------------------------------------------------------------------
|
| Migrations are disabled by default for security reasons.
| You should enable migrations whenever you intend to do a schema migration
| and disable it back when you're done.
|
*/
$config['migration_enabled'] = TRUE;
/*
|--------------------------------------------------------------------------
| Migration Type
|--------------------------------------------------------------------------
|
| Migration file names may be based on a sequential identifier or on
| a timestamp. Options are:
|
| 'sequential' = Default migration naming (001_add_blog.php)
| 'timestamp' = Timestamp migration naming (20121031104401_add_blog.php)
| Use timestamp format YYYYMMDDHHIISS.
|
| If this configuration value is missing the Migration library defaults
| to 'sequential' for backward compatibility.
|
*/
$config['migration_type'] = 'timestamp';
/*
|--------------------------------------------------------------------------
| Migrations table
|--------------------------------------------------------------------------
|
| This is the name of the table that will store the current migrations state.
| When migrations runs it will store in a database table which migration
| level the system is at. It then compares the migration level in this
| table to the $config['migration_version'] if they are not the same it
| will migrate up. This must be set.
|
*/
$config['migration_table'] = 'migrations';
/*
|--------------------------------------------------------------------------
| Auto Migrate To Latest
|--------------------------------------------------------------------------
|
| If this is set to TRUE when you load the migrations class and have
| $config['migration_enabled'] set to TRUE the system will auto migrate
| to your latest migration (whatever $config['migration_version'] is
| set to). This way you do not have to call migrations anywhere else
| in your code to have the latest migration.
|
*/
$config['migration_auto_latest'] = TRUE;
/*
|--------------------------------------------------------------------------
| Migrations version
|--------------------------------------------------------------------------
|
| This is used to set migration version that the file system should be on.
| If you run $this->migration->current() this is the version that schema will
| be upgraded / downgraded to.
|
*/
$config['migration_version'] = 1;
/*
|--------------------------------------------------------------------------
| Migrations Path
|--------------------------------------------------------------------------
|
| Path to your migrations folder.
| Typically, it will be within your application path.
| Also, writing permission is required within the migrations path.
|
*/
$config['migration_path'] = APPPATH.'migrations/';
I tried to find a solution since yesterday, but I could not find a solution.
Change 'timestamp' to 'sequential' if you want to use '001'
You have a typo in 001_Create_users.php
<? php
and
- >
For version 3.1.10 the correct path for migrations is /application/migrations.
hth
plese be sure that name of migration folder under applications to be migrations.
Hope it helps!

Migrate failing in laravel 4.2.*

I'm trying to write a simple REST API for laravel 4.2. Here is my code:
This is the command to generate two tables:
php artisan migrate:make create_users_table --table=users --create
php artisan migrate:make create_urls_table --table=urls --create
Then I added this code in up section of create_users_table.php:
$table->increments('id');
$table->string('username')->unique();
$table->string('password');
$table->timestamps();
I added this code in up section of create_urls_table.php:
$table->increments('id');
$table->integer('user_id');
$table->string('url');
$table->string('description');
$table->timestamps();
My db configurations are like this:
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'read_it_later',
'username' => '<username>',
'password' => '<password>',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
Then I added this to UserTableSeeder.php in seeds folder in database folder:
<?php
class UserTableSeeder extends Seeder {
public function run()
{
DB::table('users')->delete();
User::create(array(
'username' => 'firstuser',
'password' => Hash::make('first_password')
));
User::create(array(
'username' => 'seconduser',
'password' => Hash::make('second_password')
));
}
}
Then I uncommented $this->call('UserTableSeeder') in DatabaseSeeder.php file.
Then I ran this command:
php artisan migrate
And I got the following error:
**************************************
* Application In Production! *
**************************************
Do you really wish to run this command? y
Migration table created successfully.
[Illuminate\Database\QueryException]
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'read_it_later.users' doesn't exist (SQL: alter table `users` add `id` int unsigned not
null auto_increment primary key, add `username` varchar(255) not null, add `password` varchar(255) not null, add `created_at` timestamp default 0
not null, add `updated_at` timestamp default 0 not null)
[PDOException]
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'read_it_later.users' doesn't exist
migrate [--bench[="..."]] [--database[="..."]] [--force] [--path[="..."]] [--package[="..."]] [--pretend] [--seed]
How can I fix this error?
I just found out that I was using wrong command to generate migration tables.
I used the following commands:
php artisan migrate:make create_users_table --create=users
php artisan migrate:make create_urls_table --create=urls
Then I added my code to those files and tried these commands:
php artisan migrate
php artisan db:seed
And it worked

Laravel 4.2 auth: attempt fails

Authentication always fails (always prints bad - see the last code block below). I've tried dozens of solutions across StackOverflow.
Can anyone help me figure out what the problem is?
my user model
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'usersnew';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
my auth.php
return array(
/*
|--------------------------------------------------------------------------
| Default Authentication Driver
|--------------------------------------------------------------------------
|
| This option controls the authentication driver that will be utilized.
| This driver manages the retrieval and authentication of the users
| attempting to get access to protected areas of your application.
|
| Supported: "database", "eloquent"
|
*/
'driver' => 'eloquent',
/*
|--------------------------------------------------------------------------
| Authentication Model
|--------------------------------------------------------------------------
|
| When using the "Eloquent" authentication driver, we need to know which
| Eloquent model should be used to retrieve your users. Of course, it
| is often just the "User" model but you may use whatever you like.
|
*/
'model' => 'User',
/*
|--------------------------------------------------------------------------
| Authentication Table
|--------------------------------------------------------------------------
|
| When using the "Database" authentication driver, we need to know which
| table should be used to retrieve your users. We have chosen a basic
| default value but you may easily change it to any table you like.
|
*/
'table' => 'users',
/*
|--------------------------------------------------------------------------
| Password Reminder Settings
|--------------------------------------------------------------------------
|
| Here you may set the settings for password reminders, including a view
| that should be used as your password reminder e-mail. You will also
| be able to set the name of the table that holds the reset tokens.
|
| The "expire" time is the number of minutes that the reminder should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
The function I'm trying to run:
$input = Input::all();
$attempt = Auth::attempt( array('email' => $input['email'], 'password' => $input['password']) );
if($attempt) {
echo 123;
} else {
echo 'bad';
}
I want to thank Saint Genius and joe_archer
apparently if I don't use hashed passwords auth isn't working...
Thank you so much guys!

Benefit Of Migrations in Laravel

as In laravel we Use Migrations to Create Tables and then Seeders to seed out table, am not getting its benefit, as we can do that in normal way by just going to PHPMYADMIN then what we need to that, as we code many lines for it, but how can we justify those lines of code ?
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateItemsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('items', function(Blueprint $table)
{
$table->increments('id');
$table->integer('owner_id');
$table->string('name');
$table->boolean('done');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('items');
}
}
it is true that migrations are being created by php artisan commands, But what is the benefit of them? as we have an alternate to do that?
same for the Seeder files as we code many lines for it
class ItemTableSeeder extends Seeder{
public function run(){
DB::table('items')->delete();
$items= array(
array(
'owner_id' => '1',
'name' => 'Watch The Spectacular Now',
'done' => True
),
array(
'owner_id' => '2',
'name' => 'Watch Avengers',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'Watch The Iron man',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'Divergent',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'Bat Man',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'X-Men Days Of Future Past',
'done' => False
)
);
DB::table('items')->insert($items);
}
}
The main benefit is that you will do it in your development server/station, and you may change the schema many times in development, migrate, rollback migrations, and re-migrate them, and as soon as your application id done, you don't have to remember what you have to do in your production environment, Laravel will do it automatically for you.
Using PHPMyAdmin, you would have to create tables and edit fields manually locally and in your remote server, and you would risk forgetting something and breaking your application. And, if you have more than one server serving your application, the problem is bigger.
Migrations and seeds are database versioning. Imagine that one day you fall in love with, say PostgreSQL or anything other than MySQL. Then imagine you'd like to do some tests with more than several rows of data.. Would you run PHPMYADMIN's equivalent and insert 100, 1000 or 10000 rows?
So now check this out:
// migration
class CreateCommentsTable extends Migration {
public function up()
{
Schema::create('comments', function(Blueprint $table) {
$table->increments('id');
$table->string('body');
$table->integer('author_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->timestamps();
});
}
// seeder
class CommentsTableSeeder extends Seeder {
public function run()
{
Eloquent::unguard();
$faker = Faker::create();
foreach(range(1, 1000) as $index)
{
Comment::create([
'body' => $faker->sentence(10),
'author_id' => rand(1,20),
'post_id' => rand(1,150)
]);
}
}
Faker is a great tool you can find here: https://github.com/fzaninotto/Faker
All you need to do now is run artisan migrate --seed.
Of course there are more advantages than automating seeds, you can alter your tables with migrations in case you want to change your schema and so on.
Migration files maintains the schema of the tables. Using migration, you may never have to go to phpMyAdmin (except for creating a DB). Once done you can simply run the command 'php artisan migrate' and create the tables from the PHP side itself. Also you will never have to worry about the DB environment (MySql, Posgres, Sql Lite etc) as the migration does not truly depend on the environment to which you are migrating the tables.
Seeding helps in creating, for example, different roles (Admin, User, Editor etc) within your application. You will have to just create the seeder files and run the 'php artisan db:seed' command to populate data to the tables from the php side. Also seeds help in creating test data.

Categories