Вопрос

I'm trying to figure out the best way to do something. I have a table "groups" with a has_many relationship to another table "vehicles" (groups of vehicles). I want to query the groups table and get back an array of groups, with each group containing an array of related vehicle IDs (if any). The end result should be an JSON array of objects:

[{"id":4534,"group_name":"Annual",vehicles:[2311,3357]},{"id":4752,"group_name":"Summer",vehicles:[5,3348,4316]},{"id":4533,"group_name":"Winter",vehicles:[3116]}];

So far, with these methods:

public function vehicle()
{
    return $this->has_many('Vehicle');
}

public static function many()
{
    return self::with (array('vehicle'))
            ->where('account_id', '=', Session::get('account_id_selected'))
            ->order_by('group_name')
            ->select(array('id', 'group_name'))
            ->get();
}

I get this result:

[0] => Array
    (
        [id] => 4534
        [group_name] => Annual
        [vehicle] => Array
            (
                [0] => Array
                    (
                        [id] => 2311
                        [created] => 2007-06-01

                    )

                [1] => Array
                    (
                        [id] => 3357
                        [created] => 2008-08-25
                    )

            )

    )

[1] => Array
    (
        [id] => 4752
        [group_name] => Summer
        [vehicle] => Array
            (
                [0] => Array
                    (
                        [id] => 5
                        [created] => 0000-00-00

                [1] => Array
                    (
                        [id] => 3348
                        [created] => 2008-08-18

                [2] => Array
                    (
                        [id] => 4316
                        [created] => 2011-02-24

            )

    )

[2] => Array
    (
        [id] => 4533
        [group_name] => Winter
        [vehicle] => Array
            (
                [0] => Array
                    (
                        [id] => 3116
                        [created] => 2008-05-15

            )

    )

At the moment, after the query, I use the following to melt it all down to JSON:

 foreach (Group::many() as $group) {
      $groups[] = $group->to_array();
 }
 var Groups = {{ json_encode($groups); }};

There are two problems with the above approach (for me): (1) It returns all the fields of the vehicles table (I only want the ID). (2) I want the vehicles property to simply contain an array of IDs — not bunch of nested objects.

Now, I know can parse the vehicle property while iterating through the Eloquent object and format the query result:

$groups = array();
foreach (Group::many() as $group) {
    $v = array();
    foreach ($group->vehicle as $vehicle) {
        $v[] = $vehicle->id;
    }
    $groups[] = array('id' => $group->id, 'group_name' => $group->group_name, 'vehicles' => $v);
}
var Groups = {{ json_encode($groups); }};

But I really think this should be accomplished in the Model instead. I guess what I'm asking is, what is the best way in your opinion to go from this sort of model relationship to the resulting JSON? It is possible to eliminate the foreach loop and extra parsing code to produce the simpler JSON object described above?

Это было полезно?

Решение

Just use a join instead - more flexibility.

public static function many()
{
    return self::join('vehicles', 'vehicles.account_id', '=, 'accounts.id')
            ->where('account_id', '=', Session::get('account_id_selected'))
            ->order_by('group_name')
            ->select(array('id', 'group_name', 'vehicles.id as vehicle_id'))
            ->get();
}

Note: Im not sure of the table structure of your database so have had to assume the table names are plural and have assumed key relationships, but you should be able to work it out.

You'll then get a row, or array element for every vechicle_id that matches (i.e. id will repeat). Just run it through some sort of foreach loop to get it the way you want.

Другие советы

You can use a closure to limit what gets selected.

public static function getManyByAccountId( $account_id )
{
  return self::with (
      array(
          'vehicle' => function($query) use ($account_id ) {
             $query->select('id as vehicle_id');
          }
      )
  )->select(array('id', 'group_name'))
   ->order_by('group_name')
   ->where('account_id', '=', $account_id);
}

And the do something around:

$vehicles = json_encode( Vehicles::getManyByAccountId($account_id)->to_array() );
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top