EzDevInfo.com

eloquent interview questions

Top eloquent frequently asked interview questions

Laravel form model binding

I've been reading about this feature: http://laravel.com/docs/html#form-model-binding

And it looks really neat, but there are couple of things that I'm not certain about.

Do I need to put any code in the controller action to process this form? What does that look like?

The model (User) I want to bind in my form has a separate table for addresses. So I want to be able to fill out the User model's fields, but also the fields for the related Address model. Can I do that with form-model-binding, or do I have to handle the form manually?

Or, failing that, can I use form model binding for the user fields, but manually handle the address fields?


Source: (StackOverflow)

Laravel Eloquent: How to get only certain columns from joined tables

I have got 2 joined tables in Eloquent namely themes and users.

theme model:

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

user model:

public function themes() {
  return $this->has_many('Theme');
}

My Eloquent api call looks as below:

return Response::eloquent(Theme::with('user')->get());

Which returns all columns from theme (that's fine), and all columns from user (not fine). I only need the 'username' column from the user model, how can I limit the query to that?


Source: (StackOverflow)

Advertisements

Laravel Eloquent: Ordering results of all()

I'm stuck on a simple task. I just need to order results coming from this call

$results = Project::all();

Where Project is a model. I've tried this

$results = Project::all()->orderBy("name");

But it didn't work. Which is the better way to obtain all data from a table and get them ordered?


Source: (StackOverflow)

Using Eloquent ORM in Laravel to perform search of database using LIKE

I want to use Eloquent's active record building to build a search query, but it is going to be a LIKE search. I have found the User::find($term) or User::find(1), but this is not generating a like statement. I'm not looking for a direct answer, but if someone could at least give me a direction to look in that'd be great!


Source: (StackOverflow)

Laravel Eloquent "WHERE NOT IN"

I'm having trouble to write query in laravel eloquent ORM.

my query is

SELECT book_name,dt_of_pub,pub_lang,no_page,book_price  
FROM book_mast        
WHERE book_price NOT IN (100,200);

Now I want to convert this query into laravel eloquent.


Source: (StackOverflow)

Change default primary key in Eloquent

Can I change Eloquent model primary key.

I want to set primary key for example admin_id instead of 'id'?

I know I can change table name for model like

protected $table = "admin";

Is there something similar for primary key?


Source: (StackOverflow)

Laravel migration change and make column nullable

I created a migration with user_id unsigned. How can I edit user_id in a new migation to also make it nullable() ?

    Schema::create('throttle', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('user_id')->unsigned(); // this needs to also be nullable, how should the next migration be?
    }

Source: (StackOverflow)

Get the query executed in Laravel 3/4

How can I get the executed query in Laravel 3/4, using Fluent Query Builder or Eloquent ORM.

For example:

DB::table('users')->where_status(1)->get();

Or (posts (id, user_id, ...))

User::find(1)->posts->get();

Or... How I can save in log, all queries executed.


Source: (StackOverflow)

Laravel 4 eloquent WHERE with OR AND OR?

How do I say WHERE (a=1 OR b=1) AND (c=1 OR d=1)

For more complicated queries am I supposed to use raw SQL?


Source: (StackOverflow)

Is there a way to "limit" the result with ELOQUENT ORM of Laravel?

Is there a way to "limit" the result with ELOQUENT ORM of Laravel?

 SELECT * FROM  `games` LIMIT 30 , 30 

And with Eloquent ?


Source: (StackOverflow)

Bulk Insertion in Laravel using eloquent ORM

How can we perform bulk database insertions in Laravel using Eloquent ORM?

I want to accomplish this in Laravel: http://stackoverflow.com/a/10615821/600516 but I am getting the following error.

SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters.


Source: (StackOverflow)

How do you check "if not null" with Eloquent?

How do you check if a field is not null with Eloquent?

I tried Model::where('sent_at', 'IS NOT', DB::raw('null'))->... but it gives IS NOT as a binding instead of a comparison.

This is what DB::getQueryLog() says about it:

  'query' => string 'select * from my_table where sent_at = ? and profile_id in (?, ?) order by created_at desc' (length=101)
  'bindings' => 
    array (size=3)
      0 => string 'IS NOT' (length=6)
      1 => int 1
      2 => int 4

Source: (StackOverflow)

Laravel - Eloquent or Fluent random row

How can I select a random row using Eloquent or Fluent in Laravel framework.

I know by using SQL you can do order by RAND(). And I would prefer to do this without doing a count on the number of records prior to the initial query.

Any ideas?


Source: (StackOverflow)

Laravel 5.1 Eloquent ORM randomly returning incorrect relationship - *major update*

I have a Laravel app that powers an ecommerce website with moderate traffic. This website allows people to place orders via the frontend, but it also has backend functionality for taking orders over the phone via a call centre.

An order is related to a customer, and a customer can optionally be a user - a user being someone with a login to the frontend. A customer with no user account is only ever created as a result of an order being taken via the call centre.

The issue I have encountered is very odd, and I believe might be some kind of Laravel bug.

It only occurs very occasionally, but what is happening is that when an order is taken via the call centre for a customer with no user account, an order confirmation is being sent out to a random user - literally random, as far as I can tell, just plucked out of the database despite no relation in the data.

These are the relevant parts of the models in the project:

class Order extends Model
{
    public function customer()
    {
        return $this->belongsTo('App\Customer');
    }
}

class Customer extends Model
{
    public function orders()
    {
        return $this->hasMany('App\Order');
    }

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

class User extends Model
{ 
    public function customer()
    {
        return $this->hasOne('App\Customer');
    }
}

These are the database migrations for the above (edited for brevity):

   Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('first_name');
        $table->string('last_name');
        $table->string('email')->unique();
        $table->string('password', 60);
        $table->boolean('active');
        $table->rememberToken();
        $table->timestamps();
        $table->softDeletes();
    });

    Schema::create('customers', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('user_id')->nullable->index();
        $table->string('first_name');
        $table->string('last_name');
        $table->string('telephone')->nullable();
        $table->string('mobile')->nullable();
        $table->timestamps();
        $table->softDeletes();
    });

    Schema::create('orders', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('payment_id')->nullable()->index();
        $table->integer('customer_id')->index();
        $table->integer('staff_id')->nullable()->index();
        $table->decimal('total', 10, 2);
        $table->timestamps();
        $table->softDeletes();
    });

The logic that sends the order confirmation is within an event handler that gets fired after the order has been paid.

Here is the OrderSuccess event (edited for brevity):

namespace App\Events;

use App\Events\Event;
use App\Order;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;


class OrderSuccess extends Event
{
    use SerializesModels;

    public $order;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }
}

As can be seen, this event is passed an Order model object.

Here is the event handler (edited for brevity):

/**
 * Handle the event.
 *
 * @param  OrderSuccess  $event
 * @return void
 */
public function handle(OrderSuccess $event)
{
    // set order to paid
    $order = $event->order;
    $order->paid = date('Y-m-d H:i:s');
    $order->save();

    if(!is_null($order->customer->user)) {

        App_log::add('customer_order_success_email_sent', 'Handlers\Events\OrderSuccessProcess\handle', $order->id, print_r($order->customer, true).PHP_EOL.print_r($order->customer->user, true));

        // email the user the order confirmation
        Mail::send('emails.order_success', ['order' => $order], function($message) use ($order)
        {
            $message->to($order->customer->user->email, $order->customer->first_name.' '.$order->customer->last_name)->subject('Order #'.$order->id.' confirmation');
        });
    }

}

There is a check to see if the $order->customer->user object is not null and, if true, an order confirmation is sent. If it is null (which it frequently is), then no confirmation is sent.

As can be seen from the above, I added a log to record the objects when an email is sent. Here is an example of an erroneous one (again, truncated for brevity):

App\Customer Object
(
[attributes:protected] => Array
    (
        [id] => 10412
        [user_id] => 
        [first_name] => Joe
        [last_name] => Bloggs
        [telephone] => 0123456789
        [created_at] => 2015-09-14 13:09:45
        [updated_at] => 2015-10-24 05:00:01
        [deleted_at] => 
    )

[relations:protected] => Array
    (
        [user] => App\User Object
            (
                [attributes:protected] => Array
                    (
                        [id] => 1206
                        [email] => johndoe@whoknows.com
                        [password] => hashed
                        [remember_token] => 
                        [created_at] => 2015-09-19 09:47:16
                        [updated_at] => 2015-09-19 09:47:16
                        [deleted_at] => 
                    )
            )

    )

[morphClass:protected] => 
[exists] => 1
[wasRecentlyCreated] => 
[forceDeleting:protected] => 
)

App\User Object
(
[attributes:protected] => Array
    (
        [id] => 1206
        [email] => johndoe@whoknows.com
        [password] => hashed
        [remember_token] => 
        [created_at] => 2015-09-19 09:47:16
        [updated_at] => 2015-09-19 09:47:16
        [deleted_at] => 
    )

[morphClass:protected] => 
[exists] => 1
[wasRecentlyCreated] => 
[forceDeleting:protected] => 
)

As you can see, there is no user_id for Customer, and yet Laravel has returned a User object.

What is more, if I manually fire the exact same OrderSuccess event, the above is not reproducible - it does not send the email, and it does not load a User object.

As I said before, this issue is happening very infrequently - there are on average about 40 orders a day via the call centre for customers with no user account, and the highlighted issue might only occur once or twice a week.

I'm not familiar enough with Laravel to know what might be the issue here - is it some form of model caching, a problem with Eloquent ORM, or some other gremlin in the system?

Any ideas appreciated - I may post this problem in the Laravel github issue tracker if it appears to be some form of bug.

Update Relating to some of the answers / comments put forward, I have tried to remove any potential Eloquent ORM issues, to retrieve the data manually, like so:

$customer = Customer::find($order->customer_id);
$user = User::find($customer->user_id);

if(!is_null($user)) {
    // send email and log actions etc
}

The above is still producing the same random results - unrelated users are being retrieved even when the customer has no user_id (it's NULL in this instance).

Update 2 As the first update did not help in any way, I reverted to using the original Eloequent approach. To try another solution, I took my event code out of the event handler, and placed it in my controller - I was previously firing by OrderSuccess event using Event::fire(new OrderSuccess ($order));, and instead I commented this line out and just placed the event handler code in the controller method:

$order = Order::find($order_id);

//Event::fire(new OrderSuccess ($order));

// code from the above event handler
$order->paid = date('Y-m-d H:i:s');
$order->save();

if(!is_null($order->customer->user)) {

    App_log::add('customer_order_success_email_sent', 'Handlers\Events\OrderSuccessProcess\handle', $order->id, print_r($order->customer, true).PHP_EOL.print_r($order->customer->user, true));

    // email the user the order confirmation
    Mail::send('emails.order_success', ['order' => $order], function($message) use ($order)
    {
        $message->to($order->customer->user->email, $order->customer->first_name.' '.$order->customer->last_name)->subject('Order #'.$order->id.' confirmation');
    });
}

The above change has been on the production site for over a week now - and since that change, there has not been a single instance of the issue.

The only possible conclusion I can reach is some kind of bug in the Laravel event system, somehow corrupting the passed object. Or could something else be at play?

Update 3 It seems I was premature to state that moving my code outside the event fixed the issue - in fact, via my logging, in the last 2 days I can see some more incorrect order confirmation were sent out (a total of 5, after almost 3 weeks of no issues).

I noticed that the user ids that had received the rogue order confirmations appeared to be incrementing (not without gaps, but still in ascending order).

I also noticed that each of the problem orders had been paid for via cash and account credit - most are cash only. I looked further into this, and the user ids are actually the ids of the related credit transactions!

The above is the first cast iron breakthrough in trying to resolve this issue. On closer inspection, I can see that the issue is still random - there are quite a few (at least 50%) orders that have been paid via account credit for customer's with no user account, but that have not caused incorrect emails to be sent out (despite the associated credit transaction id having a user id match).

So, the problem is still random, or seemingly so. My credit redemption event is triggered like so:

Event::fire(new CreditRedemption( $credit, $order ));

The above is called just prior to my OrderSuccess event - as you can see, both events are passed the $order model object.

My CreditRedemption event handler looks like this:

public function handle(CreditRedemption $event)
{
    // make sure redemption amount is a negative value
    if($event->credit < 0) {
        $amount = $event->credit;
    }
    else {
        $amount = ($event->credit * -1);
    }

    // create the credit transaction
    $credit_transaction = New Credit_transaction();
    $credit_transaction->transaction_type = 'Credit Redemption';
    $credit_transaction->amount = $amount; // negative value
    $credit_transaction->customer_id = $event->order->customer->id;
    $credit_transaction->order_id = $event->order->id;

    // record staff member if appropriate
    if(!is_null($event->order->staff)) {
        $credit_transaction->staff_id = $event->order->staff->id;
    }

    // save transaction
    $credit_transaction->save();

    return $credit_transaction;
}

The $credit_transaction->save(); is generating the id in my credit_transactions table that is somehow being used by Laravel to retrieve a user object. As can be seen in the above handler, I'm not updating my $order object at any point.

How is Laravel using (remember, still randomly, some < 50% of the time) the id of my newly created $credit_transaciton to populate the $order->customer->user model object?


Source: (StackOverflow)

Managing relationships in Laravel, adhering to the repository pattern

While creating an app in Laravel 4 after reading T. Otwell's book on good design patterns in Laravel I found myself creating repositories for every table on the application.

I ended up with the following table structure:

  • Students: id, name
  • Courses: id, name, teacher_id
  • Teachers: id, name
  • Assignments: id, name, course_id
  • Scores (acts as a pivot between students and assignments): student_id, assignment_id, scores

I have repository classes with find, create, update and delete methods for all of these tables. Each repository has an Eloquent model which interacts with the database. Relationships are defined in the model per Laravel's documentation: http://laravel.com/docs/eloquent#relationships.

When creating a new course, all I do is calling the create method on the Course Repository. That course has assignments, so when creating one, I also want to create an entry in the score's table for each student in the course. I do this through the Assignment Repository. This implies the assignment repository communicates with two Eloquent models, with the Assignment and Student model.

My question is: as this app will probably grow in size and more relationships will be introduced, is it good practice to communicate with different Eloquent models in repositories or should this be done using other repositories instead (I mean calling other repositories from the Assignment repository) or should it be done in the Eloquent models all together?

Also, is it good practice to use the scores table as a pivot between assignments and students or should it be done somewhere else?


Source: (StackOverflow)