I've followed Jeffrey Way's explanation and several other blog posts and articles, yet still cannot get this to work.
I want to use the Eloquent ORM outside of Laravel. I've included the requirements in my composer.json:
"illuminate/database": "v5.*",
"illuminate/events": "v5.*",
Then I instantiated the Capsule Manager:
$db = new Illuminate\Database\Capsule\Manager();
$db->addConnection($config['database']);
$db->setEventDispatcher(new Illuminate\Events\Dispatcher(new Illuminate\Container\Container));
$db->setAsGlobal();
$db->bootEloquent();
I've built a basic User model that extends the Eloquent Model:
use Illuminate\Database\Eloquent\Model as Eloquent;
class User extends Eloquent
{
public $incrementing = false;
protected $primaryKey = 'username';
protected $keyType = 'string';
}
Now I can create a new User as intended:
$u = new User([
'username' => $username,
'fullname' => $fullname,
'role_id' => $role_id,
]);
$u->save();
And this works like a charm, the user appears in the intended users table fine, yet I can't retrieve a user by any of these methods, my response is always null:
$user = User::find('foo'); // no dice
$user = User::where('username', 'foo')->get(); // nope
$user = User::first(); // nothing
Does anyone know why I can't use the static methods that come with Eloquent models? Or better yet, how to fix this?
Related
I have got a dev database and a live database. I need to return some results from the live database but only for one method within this model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class TableName extends Model
{
protected $table = 'table_name';
protected $connection = 'dev';
public $timestamps = false;
public static function live($index) {
$liveId = Settings::where('index', $index)->get()[0];
$live = new TableName;
$live->setConnection('live');
$data = $live::where('index', $liveId->live_index)->get();
dd($live);
return $data;
}
}
If I dd() the $live variable after calling setConnection then it does say that the connection is indeed live. However as soon as I dd() the $data I get the rows from the dev database!
Eloquent provides a nice way to handle multiple connections.
You should just be able to use the on method. For example.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class TableName extends Model
{
protected $table = 'table_name';
protected $connection = 'dev';
public $timestamps = false;
public static function live($index) {
$liveId = Settings::where('index', $index)->get()[0];
$data = self::on('live')->where('index', $liveId->live_index)->get();
return $data;
}
}
That should then run the query using the live connection in your database configuration.
I have personally haven't done anything like this, but I found out way to do this by following these steps.
In the .env file add these new env variables =>
DB_CONNECTION_2=mysql
DB_HOST_2=127.0.0.1
DB_PORT_2=3306
DB_DATABASE_2=database2
DB_USERNAME_2=root
DB_PASSWORD_2=secret
Now inside the config/database.php file specify the 2nd mysql connection with the previously entered env variables.
'mysql2' => [
'driver' => env('DB_CONNECTION_2'),
'host' => env('DB_HOST_2'),
'port' => env('DB_PORT_2'),
'database' => env('DB_DATABASE_2'),
'username' => env('DB_USERNAME_2'),
'password' => env('DB_PASSWORD_2'),
],
Now you can create a Model for the required table =>
class myModel extends Eloquent {
protected $connection = 'mysql2';
}
Then you can use it as the regular way will all the Eloquent features in controller methods =>
$newMy = new myModel;
$newMy->setConnection('mysql2');
$newMy = $someModel->find(1);
return $something;
Here is the doc link that you can read about this more.
You can try to get the default connection before the point with
$defaultConnection = DB::getDefaultConnection();
then change the default connection to before obtaining the results from 'live'
DB::setDefaultConnection('live');
and then restore the connection as soon as 'live' connection is no longer needed
DB::setDefaultConnection($defaultConnection);
As an alternative you can generate your data using DB::connection('live'). More info at Using Multiple Database Connections
I have write my code to instantiate Eloquent Capsule/Manager using slim DI like this
$container['db'] = function ($c) {
$settings = $c->get('database');
$db = new \Illuminate\Database\Capsule\Manager;
$db->addConnection($settings);
$db->setAsGlobal();
$db->bootEloquent();
return $db;
}
And I have my route like this
$app->get('/adduser', function() {
$user = new Users;
$user->name = "Users 1";
$user->email = "user1#test.com";
$user->password = "My Passwd";
$user->save();
echo "Hello, $user->name !";
});
When I run the route in browser it will produce error in web server error log
PHP Fatal error: Call to a member function connection() on a non-object in /home/***/vendor/illuminate/database/Eloquent/Model.php on line 3335
In my opinion this is happened because the Eloquent Capsule/Manager is not triggered to be instantiate by DI.
I found a solution to solve this by declare the Model with custom constructor like this
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Capsule\Manager as Capsule;
class Users extends Eloquent {
protected $table = 'users';
protected $hidden = array('password');
public function __construct(Capsule $capsule, array $attributes = array())
{
parent::__construct($attributes);
}
}
But I don't think this is a clean solutions, because I have to rewrite all my Models using custom constructor.
I need help to find solutions for my problem.
I try to use code below:
$app->get('/adduser', function() use ($some_variable) {
// create user script
});
but so far I don't know how to trigger $container['db'] using this method. I really appreciate a help here.
It's probably not a good idea to inject your capsule manager into each model.. As you say yourself, that's going to be a pain to manage.
Have you tried this code outside of the closure? ie. in the bootstrap part of your app..
$db = new \Illuminate\Database\Capsule\Manager;
$db->addConnection($settings);
$db->setAsGlobal();
$db->bootEloquent();
The setAsGlobal function makes the Capsule Manager instance static, so the models can access it globally.
Just to note, convention is to name your model classes in singular form. ie. User rather than Users.
I seem to be stumped on how to automatically save related models when creating a model instance in Laravel. Consider:
A User Model:
<?php
// file: User.php
class User extends Eloquent
{
public function role()
{
$this->hasOne('Role');
}
}
A Role Model:
<?php
// file: Role.php
class Role extends Eloquent
{
public function user()
{
$this->belongsTo('User');
}
}
Now lets say I want to create a new user and assign a it a role. Its quite easy to get the association to work if I set the role relationship after I save the user. For example, this works great:
$user = new User();
$user->name = 'Bobby';
$user->save();
$role = new Role();
$role->type = "Super Hero";
$user->role()->save($role);
However, if I want to push or cascade the save it fails to assign the foreignKey. I'd like to save() only once, and have the relationships save via cascade. For example, this doesn't work:
$user = new User();
$user->name = 'Bobby';
$role = new Role();
$role->type = "Super Hero";
$user->role = $role; // or $user->role()->save($role);
$user->save(); // push()?
This would be somewhat similar to how Doctrine 2 handles persisting. Is it possible to create both at the same time in Eloquent?
I have a user model defined, and I'm trying to add a new user in my database using a form, what is the best and fastest way to do it, I have read something about model forms binding but I think it's just for updating not for adding new rows.
I'm new in Laravel and couldn't find some good tutorials, I must recognize that Laravel documentation is really poor, so any links to some good and well explained tutorials are welcomed.
Thank you
Assumed that, you have a User model (app/models/User.php) the one came with Laravel by default, which may look like this:
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $table = 'users';
protected $hidden = array('password');
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword()
{
return $this->password;
}
public function getReminderEmail()
{
return $this->email;
}
}
Now, from a controller (Basically) you may use somethng like this:
$user = new user;
$user->username= 'Me';
$user->email = 'me#yahoo.com';
// add more fields (all fields that users table contains without id)
$user->save();
There are other ways, for example:
$userData = array('username' => 'Me', 'email' => 'me#yahoo.com');
User::create($userData);
Or this:
User::create(Input::except('_token'));
This requires you to use a property in your User model like this:
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $fillable = array('username', 'email');
// Or this, (Read the documentation first before you use it/mass assignment)
protected $guarded = array();
}
Since, you are still new to Laravel you may use first example and read about Mass Assignment, then you may use the second one if you want.
Update:
In your controller, you may use Input::get('formfieldname') to get the submitted data, for example:
$username = Input::get($username);
So, you can use these data like this:
$user = new User;
$user->username= $username;
Or directly you can use:
$user->email = Input::get($email);
$user->save();
In the form, you have to set the form action, where you'll submit the form and in this case you have to declare a route, for example:
Route::post('user/add', array('as' => 'user.add', 'uses' => 'UserController#addUser'));
Then in your controller you have to create the method addUser, like this:
class UserController extends addUser {
// other methods
public function addUser()
{
$user = new user;
$user->username = Input::get('username');
$user->email = Input::get($email);
$user->save();
}
}
In your form you may use this:
Form::open(array('route' => 'user.add'))
Read the documentation properly, you can do it easily.
I'm currently injecting my eloquent models in my controllers like this:
class ComputerController extends BaseController {
public function __construct(User $user, Machine $machine, MachineType $machineType){
$this->user = $user;
$this->machine = $machine;
$this->machineType = $machineType;
}
So I can access the models quickly with:
$this->machine->get();
But how to I access the properties such as validation rules that are stored in the class?
I used to use
Machine::$rules;
But using this method
$this->machine->$rules
Does not work. Is there a way to retrieve the rules array that is stored in the eloquent model?
This is my class as an example:
class Machine extends Eloquent {
protected $table = 'machines';
public $timestamps = true;
protected $softDelete = true;
public static $rules = array(
'computer_name' => 'required|min:2',
'computer_user' => 'required',
'computer_ip' => 'ip'
);
Thanks a lot!
Edit:: Tried this according to Antonio just to test, still no avail, brings an error when I run it.
Error:
For static variables, this should work fine:
$this->machine::$rules
EDIT:
Somehow using an object this way it doesn't work, but here's a workaround:
$machine = $this->machine;
dd($machine::$rules);