2

I'm writing a system around an existing database structure using Laravel 4.1. The current system is based around two websites which use their own table, a and b, both of which are identical. This is an unavoidable problem until we rewrite the other system.

I need to be able to query both tables at the same time using Eloquents Query Builder, so I may need to get a list of rows from both tables, or INSERT or UPDATE from either at any time.

Currently we have a model for both tables, but no way to link between them and implement the missing methods such as all or find.

Our thought is to have an Interface which will bind these results together, however we're not sure how to go about this at all.

<?php

    interface HotelInterface {
        public function all();
        public function find();
    }

    use Illuminate\Database\Model;

    class Hotel implements HotelInterface {

    }

?>

Is all we have so far.

3
  • Are these two databases on the same server? Commented Feb 10, 2014 at 18:11
  • @DavidBarker yes they are, but they're in a different database to what the main models are. This isn't the problem though. Commented Feb 11, 2014 at 8:41
  • Sorry, I wasn't trying to point out a problem... I needed to know if there were on the same server to propose a potential solution. Commented Feb 11, 2014 at 14:06

3 Answers 3

2

I asked on the Laravel forums and got the answer I was looking for! I'm reposting here incase.

What we're actually after is a Repository which would look like this:

<?php
    class HotelRepository {
        public $A;
        public $B;

        public function __construct(A $A, B $B) {
            $this->A = $A;
            $this->B  = $B;
        }

        public function find($iso = NULL, $hotelid = NULL) {
            $A = $B = NULL;

            if($iso !== NULL) {
                $A = $this->A->where('country', $iso);
                $B  = $this->B->where('country', $iso);

                if($hotelid !== NULL) {
                    $A = $A->where('id', $hotelid);
                    $B = $B->where('id', $hotelid);
                }
            }

            if($hotelid !== NULL) {
                if($A->first()) {
                    return $A->first();
                }
                if($B->first()) {
                    return $B->first();
                }
            }else{
                return $A->get()->merge($B->get());
            }
        }

        public function all() {
            $aCollection = $this->A->all();
            $bCollection  = $this->B->all();
            return $aCollection->merge($bCollection);
        }
    }

Now in the controller where I want to call this, I just add:

<?php
    class HomeController extends BaseController {
        public function __construct(HotelRepository $hotels) {
            $this->hotels = $hotels;
        }
    }

And I can now use $this->hotels to access the find and all method that I created.

Sign up to request clarification or add additional context in comments.

Comments

1

If the tables are identical you should only need one model, the connection is the only thing that needs to change. Have a read here: http://fideloper.com/laravel-multiple-database-connections.

There's a Eloquent method on() for specifying the connection, here's an example:

The Eloquent example looks like what you need:

$results = Model::on('mysql')->find(1);

Add both connections to your database config and then change the on() part depending on which DB you need to query.

Update: misunderstood the question

If you only need to change the table and not the database, you can use setTable()

$model = new Model
$model->setTable('b');
$model->find(1);

Although that may get confusing.

Instead, you could also define a base model and then extend it with the only difference being the table protected $table = 'b';

5 Comments

Thanks, but I'm not using a different database.
Ah, sorry. You just want setTable then.
@James I'm confused.... are these or aren't these on different databases? Now you're saying they're just different tables within the same DB?
These two tables are on one database, but the rest of the system is in a different one.
If only these tables are on different databases then use protected $connection = 'mysql2'; in the model too
0

You can always change the default database for the one you need. I use this Config::set('database.default', 'chronos');, where chronos is one of my databases. When I need to change to the "other", I just change de database name. You can call it wherever you want. I think that what you're looking for is just switch between the databases.

You need to have two different models, one for each table on each database, though.

Let me know if I got it wrong.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.