laravel BelongsTo relationship with different databases not working

后端 未结 9 934
無奈伤痛
無奈伤痛 2020-12-06 00:25

I\'ve seen in several places to \"stay away\" from this, but alas - this is how my DB is built:

class Album extends Eloquent {

   // default connection

            


        
相关标签:
9条回答
  • 2020-12-06 00:26

    This is the way it worked for me:

    In my .env and config/database.php i have defined my other connection => How to use multiple databases in Laravel

    I updated my model this way:

    class MyOtherDBModel extends Model
    {
        protected $table = 'tablename';
        protected $connection = 'mysql2';
    
        public function __construct(array $attributes = [])
        {
            $this->table = env('DB_DATABASE_2').'.'.$this->table;
            parent::__construct();
        }
    }
    
    class MyModel extends Model
    {
        public function myOtherModel()
        {
            return $this->belongsTo(MyOtherDBModel::class, 'field', 'field');
        }
    }
    

    Now i can call

    $query = MyModel::whereHas('myOtherModel');
    
    0 讨论(0)
  • 2020-12-06 00:29

    I had the same issue when relationship wasn't working off the model connection.

    My solution was to override the belongsToMany method on the model trying to establish. See example below.

    <?php
    
    namespace App\Model;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Relations\BelongsToMany;
    
    class ConnectionModel extends Model
    {
        /**
         * Override method to allow inheriting connection of parent
         *
         * Define a many-to-many relationship.
         *
         * @param  string  $related
         * @param  string  $table
         * @param  string  $foreignKey
         * @param  string  $otherKey
         * @param  string  $relation
         * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany|BelongsToMany
         */
        public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
        {
            // If no relationship name was passed, we will pull backtraces to get the
            // name of the calling function. We will use that function name as the
            // title of this relation since that is a great convention to apply.
            if (is_null($relation)) {
                $relation = $this->getBelongsToManyCaller();
            }
    
            // First, we'll need to determine the foreign key and "other key" for the
            // relationship. Once we have determined the keys we'll make the query
            // instances as well as the relationship instances we need for this.
            $foreignKey = $foreignKey ?: $this->getForeignKey();
    
            $instance = new $related;
    
            // get connection from parent
            $instance->setConnection(parent::getConnectionName());
    
            $otherKey = $otherKey ?: $instance->getForeignKey();
    
            // If no table name was provided, we can guess it by concatenating the two
            // models using underscores in alphabetical order. The two model names
            // are transformed to snake case from their default CamelCase also.
            if (is_null($table)) {
                $table = $this->joiningTable($related);
            }
    
            // Now we're ready to create a new query builder for the related model and
            // the relationship instances for the relation. The relations will set
            // appropriate query constraint and entirely manages the hydrations.
            $query = $instance->newQuery();
    
            return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation);
        }
    }
    
    0 讨论(0)
  • 2020-12-06 00:34

    It looks like Eager Loading will do what you want to do

    Album::with(['genre' => function ($q) {
       $q->connection('Resources')
         ->where('genre', 'German HopScotch'); 
    }]);
    
    0 讨论(0)
  • 2020-12-06 00:37

    Solution for laravel v5.7 and above

    class Album extends Eloquent {
    
       // default connection
    
       public function genre() {
           return $this->setConnection('Resources')->belongsTo('genre');
       }
    ...
    }
    
    
    0 讨论(0)
  • 2020-12-06 00:37

    Add the connection variable with the default connection on the genre model:

    protected $connection = 'mysql';
    

    I had some problems with the relationships by not adding this.

    0 讨论(0)
  • 2020-12-06 00:41

    I found a really good article for this here: http://fideloper.com/laravel-multiple-database-connections

    You basically have to specify your two connections in your config file like so:

    <?php
    return array(
    
        'default' => 'mysql',
    
        'connections' => array(
    
            # Our primary database connection
            'mysql' => array(
                'driver'    => 'mysql',
                'host'      => 'host1',
                'database'  => 'database1',
                'username'  => 'user1',
                'password'  => 'pass1'
                'charset'   => 'utf8',
                'collation' => 'utf8_unicode_ci',
                'prefix'    => '',
            ),
    
            # Our secondary database connection
            'mysql2' => array(
                'driver'    => 'mysql',
                'host'      => 'host2',
                'database'  => 'database2',
                'username'  => 'user2',
                'password'  => 'pass2'
                'charset'   => 'utf8',
                'collation' => 'utf8_unicode_ci',
                'prefix'    => '',
            ),
        ),
    );
    

    So your two connections are aliased to mysql and mysql2.

    Then you can tell eloquent which 'alias' to use like so:

    <?php
    
    class SomeModel extends Eloquent {
    
        protected $connection = 'mysql2';
    
    }
    

    Then you can setup your relationships like normal.

    tl;dr: Basically instead of specifying the table name as $connection in eloquent, specify the connection alias in your configuration and it should work.

    0 讨论(0)
提交回复
热议问题