Prepend the database name to the $table value in class User. So assuming seven_ora is also the name of the DB:
protected $table = 'seven_ora.userinfo';
Вопрос
I am using MSSQL having 2 connections named seven_ora (which a User model's table is in), and sho (which a Character model's table is in).
A user hasMany characters, and a character belongsTo user.
When I try:
Character::whereHas('User', function($q) { $q->where('gm', 1); });
It seems to use the same connection as Character. And it seems that the closure in whereHas is a Query\Builder? I expected the whereHas to use the respective set connection of whatever model it is referring to.
Is there a way to use a different connection on my whereHas closure?
Characters.php (Model)
class Character extends Base {
/**
* Connection used by the model
*
* @var string
*/
protected $connection = 'sho';
/**
* Table used by the model
*
* @var string
*/
protected $table = 'tblgs_avatar';
/**
* Fields fillable by the model
*
* @var array
*/
protected $guarded = array('*');
/**
* Checks whether the model uses timestamps
*
* @var boolean
*/
public $timestamps = false;
/**
* Decode the job name of the given ID
*
* @return string
*/
public function getJobName()
{
switch( $this->job ) {
case 0:
$job = 'Visitor';
break;
case 111:
$job = 'Solider';
break;
case 221:
$job = 'Muse';
break;
case 311:
$job = 'Hawker';
break;
case 411:
$job = 'Dealer';
break;
case 121:
$job = 'Knight';
break;
case 122:
$job = 'Champ';
break;
case 221:
$job = 'Mage';
break;
case 222:
$job = 'Cleric';
break;
case 321:
$job = 'Raider';
break;
case 322:
$job = 'Scout';
break;
case 421:
$job = 'Bourg';
break;
case 422:
$job = 'Artisan';
break;
default:
$job = 'Untitled';
break;
}
return $job;
}
/**
* Rank the characters according to provided details
*
* @param integer $offset
* @param string $field
* @return Character
*/
public static function byTop($offset = 10, $field = null)
{
$characters = new static();
if ( !is_null($field) ) $characters->orderBy($field, 'desc');
return $characters->take($offset);
}
/**
* A shortcut to access the name of the character
*
* @return string
*/
public function getNameAttribute()
{
return $this->txtNAME;
}
/**
* A shortcut to access the level of the character
*
* @return int
*/
public function getLevelAttribute()
{
return $this->btLEVEL;
}
/**
* A shortcut to access the job of the character
*
* @return integer
*/
public function getJobAttribute()
{
return $this->intJOB;
}
/*
|--------------------------------------------------------------------------
| ORM
|--------------------------------------------------------------------------
*/
/**
* ORM with the [User] table
*
* @return User
*/
public function user()
{
return $this->belongsTo('User', 'Account', 'txtACCOUNT');
//$user = User::where('Account', $this->txtACCOUNT)->first();
//return $user;
}
}
User.php (Model)
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Base implements UserInterface, RemindableInterface {
/**
* Connection used by the model
*
* @var string
*/
protected $connection = 'seven_ora';
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'userinfo';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = array('MD5PassWord', 'password');
/**
* Fields guarded by the model
*
* @var array
*/
protected $guarded = array();
/**
* Fields fillable by the model
*
* @var array
*/
protected $fillable = array(
'Account',
'Email',
'MD5PassWord',
'FirstName',
'LastName',
'MotherLName'
);
/**
* Checks whether the model uses timestamps
*
* @var boolean
*/
public $timestamps = false;
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->MD5PassWord;
}
/**
* Get the token value for the "remember me" session.
*
* @return string
*/
public function getRememberToken()
{
return $this->remember_token;
}
/**
* Set the token value for the "remember me" session.
*
* @param string $value
* @return void
*/
public function setRememberToken($value)
{
$this->remember_token = $value;
}
/**
* Get the column name for the "remember me" token.
*
* @return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Get the e-mail address where password reminders are sent.
*
* @return string
*/
public function getReminderEmail()
{
return $this->email;
}
/**
* Validate input
*
* @param array $input
* @param integer $id
* @return Validator
*/
public function validate(array $input = array(), $id = null)
{
// Rules
$username = 'required|alpha_num|between:4,32|unique:userinfo,Account';
$password = 'required|between:4,48';
$email = 'required|email|unique:userinfo,Email';
$mname = 'required';
// Unique rules
if(!is_null($id)) {
$unique = ',' . $id;
$username .= $unique;
$email .= $unique;
}
$rules = array(
'username' => $username,
'password' => $password,
'email' => $email,
'mname' => $mname
);
$messages = array('mname.required' => "The security question field is required");
Config::set('database.default', 'seven_ora'); // Set config
return Validator::make($input, $rules, $messages);
}
/**
* Change password of the user
*
* @param string $old
* @param string $new
* @return boolean
*/
public function changePassword($old, $new)
{
if(Hash::check($old, $this->MD5PassWord)) {
$this->MD5PassWord = Hash::make($new);
if($this->save()) return true;
}
return false;
}
/**
* Checks if the user is a GM
*
* @return boolean
*/
public function isGM()
{
return ( $this->Right > 1 )
? true
: false;
}
public function addVP($points)
{
$vp = $this->votePoint;
$count = $vp->count;
$vp->count = $count + $points;
$vp->save();
}
/**
* Since our server files does not use the typical
* field names, this sets our username to whatever is being used
*
* @return void
*/
public function getUsernameAttribute()
{
return $this->Account;
}
/**
* Since our server files does not use the typical
* field names, this sets our password to whatever is being used
*
* @return void
*/
public function getPasswordAttribute()
{
return $this->MD5PassWord;
}
/**
* A shortcut to the user's vote point count
*
* @return void
*/
public function getVpAttribute()
{
return $this->votePoint->count;
}
public function getDpAttribute()
{
return $this->donationPoint->count;
}
/*
|--------------------------------------------------------------------------
| ORM
|--------------------------------------------------------------------------
*/
/**
* ORM with the Character model
*
* @return Character
*/
public function characters()
{
return $this->hasMany('Character', 'txtACCOUNT', 'Account');
//$characters = Character::where('txtACCOUNT', $this->username)->get();
//return $characters;
}
/**
* ORM with the VotePoint model
*
* @return VotePoint
*/
public function votePoint()
{
return $this->hasOne('VotePoint');
}
/**
* ROWM with the DonationPointmodel
*
* @return DonationPoint
*/
public function donationPoint()
{
return $this->hasOne('DonationPoint');
}
/**
* ORM with the News model
*
* @return News
*/
public function news()
{
return $this->hasMany('News');
}
/**
* ORM with the Slide model
*
* @return Slide
*/
public function slides()
{
return $this->hasMany('Slide');
}
/**
* ORM with the VoteLog model
*
* @return VoteLog
*/
public function logs()
{
return $this->hasMany('VoteLog');
}
}
Решение
Prepend the database name to the $table value in class User. So assuming seven_ora is also the name of the DB:
protected $table = 'seven_ora.userinfo';
Другие советы
You can also add it via a config variable in constructor to accommodate different environments
public function __construct($attributes = array()) {
parent::__construct($attributes);
$this->table = Config::get('database.connections.connection.database').'.model_table_name';
}
This might help:
SELECT *
FROM characters
WHERE (SELECT COUNT(*) FROM users WHERE characters.user_id = user.id AND gm = 1) >= 1;
[uses the connection defined on the Character model (as you have noticed)]SELECT * FROM characters;
[uses connection defined on the Character model]SELECT * FROM users WHERE id IN (1, 2, 3, …);
[uses connection defined on the User model]Prepending the database name to the table name, as the solution suggests, will only work if the Character model connection has privileges to access the other database, because you are still using the Character model connection.