简体   繁体   中英

Laravel 4 : How to retrieve data in a one-to-many relationship?

(See codes below)

I have two models User and Messages. I want to take 10 messages- with their associated sender name -based on each of the inputted conversation id and reverse the data. I have already succeeded in getting the messages but couldn't scale it down to 10 messages each conversation/with their associated sender name.

  1. I have tried this to return the messages data with the users data but either I don't know how to access the sender's name or it doesn't return the associated user :

     $allMessages = Messages::with('User')->whereIn('conv_id',$conv_id); 
  2. I have also tried this to return 10 messages but it returns 10 messages based on all the messages it got instead of based on each conversation.

     $allMessages = Messages::whereIn('conv_id',$conv_id)->take(10); 

How do I get 10 messages based on the id of each conversation together with the messages' associated sender name? Bonus points for improvement of code. Thank you in advance!


User model

public function messages(){
    return $this->hasMany('Messages');
}

Messages model

public function user(){
    return $this->belongsTo('User');
}

Controller

public function index()
    {
        $timestamps = Input::get('from'); //timestamp of latest message
        $conv_id = Input::get('conv_id'); //array of conversation ids
        $allMessages = Messages::whereIn('conv_id',$conv_id);
        if(is_null($timestamps)){
           $messages = $allMessages->orderBy('created_at','desc');
        }else{
           asort($timestamps);
           $messages = $allMessages->where('created_at','>',end($timestamps));
        }
        return $messages->get()->reverse();
    }

Migrations

Messages table

Schema::create('messages', function(Blueprint $table)
        {
            $table->increments('id');
            $table->integer('user_id');
            $table->integer('conv_id');
            $table->text('body');
            $table->timestamps();
        });

User table

Schema::create('users',function($table)
        {
            $table->increments('id');
            $table->string('email')->unique();
            $table->string('password',100);
            $table->string('name',150);
            $table->string('usertype',50);
            $table->boolean('block');
            $table->string('remember_token',100);
            $table->timestamp('lastlogin_at');
            $table->timestamps();
            $table->softDeletes();
        });

EDIT : var_dump preview result of WereWolf's answer in chrome

0: {id:37, user_id:1, conv_id:2, body:damn mate, created_at:2014-06-20 00:55:32,…}
1: {id:38, user_id:1, conv_id:2, body:hello, created_at:2014-06-20 02:18:21,…}
2: {id:39, user_id:1, conv_id:2, body:dude, created_at:2014-06-20 02:20:10,…}
3: {id:40, user_id:1, conv_id:2, body:test, created_at:2014-06-20 06:52:37,…}
4: {id:67, user_id:1, conv_id:2, body:haha, created_at:2014-06-21 01:25:56,…}
5: {id:68, user_id:1, conv_id:2, body:hey, created_at:2014-06-21 01:26:14, updated_at:2014-06-21 01:26:14,…}
6: {id:69, user_id:1, conv_id:1, body:testa, created_at:2014-06-21 01:27:02,…}
7: {id:70, user_id:1, conv_id:1, body:testser, created_at:2014-06-21 01:27:32,…}
8: {id:115, user_id:1, conv_id:2, body:haha, created_at:2014-06-21 02:45:06,…}
9: {id:116, user_id:1, conv_id:2, body:test, created_at:2014-06-21 02:57:03,…}

You may try this:

$allMessages = Messages::with('user')
                       ->where('conv_id', $conv_id)
                       ->take(10)
                       ->get();

This will return a collection of Messages model so you need to loop like:

@foreach($allMessages as $message)
    {{ $message->user->name }}
    {{ $message->body }}
@endforeach

Also, you may use:

// Get the first message and then user->name
$allMessages->first()->user->name;

// Get the second message and then user->name
$allMessages->get(1)->user->name;
public function PurchaseReport () {

            $heartsPurReport = DB::table('users')

                        ->join('heartz_payment', 'users.id', '=', 'heartz_payment.user_id')
                        ->join('heartz_transaction', 'users.id', '=', 'heartz_transaction.user_id')
                        ->select('users.username', 'users.email', 'heartz_payment.heartz', 'heartz_payment.transaction_id', 'heartz_payment.order_id', 'heartz_payment.created_at', 'heartz_payment.status',  'heartz_payment.amount', 'heartz_transaction.event')->paginate(20);

//dd(json_encode($heartsPurReport));

                        return view('Reports.Heartz.Purchase')->with('heartz',  $heartsPurReport);                          
    }

// in view use foreach loop and use the following for pagination outside foreach loop

                       {!! $consumption->render() !!}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM