Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 29.10.2012 10:45:50

update из-под Eloquent

Не совсем врубаюсь пока в механику работы Eloquent’a. Есть следующие модели:

PHP
// User
class User extends Eloquent
{
    public function 
account() {
        return 
$this->has_many('Account');
    }
}

// Account
class Account extends Eloquent
{
    public function 
user() {
        return 
$this->belongs_to('User');
    }
}

Попытка сделать следующее:

PHP
$credits 10;
User::find(Auth::user()->id)->account()->save(array('summa' => DB::raw('summa + ' $credits));

приводит к Argument 1 passed to Laravel\Database\Eloquent\Model::fill() must be an array, string given, менял условия, упращал вплоть до примера из http://laravel.ru/articles/rees/eloquent — все едино, одна и таже ошибка. ЧЯДНТ?

Вообще, в оригинале, хотелось бы не городить огород с DB::raw вообще, а вынести все операции с базой в модель, где собственно этому и место, что то типа:

PHP
// User
class User extends Eloquent
{
    public function 
account() {
        return 
$this->has_many('Account');
    }
}

// Account
class Account extends Eloquent
{
    public function 
user() {
        return 
$this->belongs_to('User');
    }

    public function 
add_demo_credits($credits) {
        if (
$this->get_attribute('demo_flag') === 'demo') {
            
$credits += $this->get_attribute('summa');
            
$this->set_attribute('summa'$credits);
        }
    }
}

Поскольку записей в Account приходится по две на одного User, а разница в демо_флаге, то хотелось бы разделить на два метода в модели, чем добавлять условие ->where в запрос контроллера. Но и в этом случае я не знаю как достучаться до этого метода add_demo_credits($credits) отталкиваясь от Auth::user(). Не подскажете, как это сделать просто и красиво?

Не в сети

#2 29.10.2012 11:02:13

Re: update из-под Eloquent

PHPEloquent->save() никак не может работать в такой форме, у него нет аргументов. Да и в целом команду можно упростить:

PHP
User::find(Auth::user()->id)->account()->save(array('summa' => DB::raw('summa + ' $credits));

PHP
Auth::user()->account()->fill(array('summa' => "summa + $credits"))->save();

Обрати внимание, что PHPAuth::user() может вернуть null, поэтому перед таким запросом всегда проверяй, что кто-то авторизован — PHPAuth::check() или PHPAuth::guest() (обратное).

  1. PHP$this->get_attribute('demo_flag')

Это можно просто заменить на PHP$this->demo_flag; тоже самое с PHPset_attribute().

  1. Поскольку записей в Account приходится по две на одного User, а разница в демо_флаге, то хотелось бы разделить на два метода в модели

Можно так:

PHP
    public function demoAccount() {
        return 
$this->has_many('Account')->where('demo_flag''=''demo');
    }

    public function 
account() {
        return 
$this->has_many('Account')->where('demo_flag''!=''demo');
    }

Не в сети

#3 29.10.2012 13:27:33

Re: update из-под Eloquent

при вызове:

PHP
Auth::user()->demoAccount()->fill(array('summa' => "summa+ $credits"))->save();

бросается эксепшен: Method [fill] is not defined on the Query class., заменил на

PHP
Auth::user()->demoAccount()->update(array('summa' => "summa+ $credits"));

тут выругался на SQLSTATE[HY000]: General error: 1366 Incorrect decimal value: 'summa+ 1.00' for column 'summa', не желает это цеплять на `summa` = ? в SQL запросе, фиг с ним, заменил в итоге на:

PHP
Auth::user()->demoAccount()->update(array('summa' => DB::raw('summa+ ' $credits)));

и все поехало как надо. Большое спасибо за совет. Теперь чуть лучше представляю себе как это делать через Eloquent, а то с горя думал перевести проект под Fluent ☺

Не в сети

#4 29.10.2012 13:33:53

Re: update из-под Eloquent

Насчет Auth::user(), эту штуку я проверяю через фильтр before в маршруте перед вызовом контроллера, но совсем упустил из виду момент, что перейти то юзер перешел, но вот после может провисеть без активных действий до экспаеринга сессии и как только совершит действия, тут от этот нулл и вылезет, а перехвата нет, только что проверил и получил висящего и ничего не понимающего «что происходит?» юзера в мемберке.

PS: действия пользователя шли через Ajax, фильтр то отработал свое, но ничего в обратку JS не вернул, так что все равно — бага :D

Изменено John (29.10.2012 13:38:16)

Не в сети

#5 29.10.2012 13:46:15

Re: update из-под Eloquent

вот такая штука решает эту проблему:

PHP
Route::filter('member::auth', function () {
    if (
Auth::guest()) {
        if (
Request::ajax()) {
            echo 
'session_dropped';
            exit;
        } else {
            return 
Redirect::to_action('member::auth@login');
        }
    }
});

ну и в JS ловить session_dropped и пробрасывать на базу.

Не в сети

#6 29.10.2012 21:57:08

Re: update из-под Eloquent

fill()->save() ты правильно заменил на update().

Насчёт summa я не понял сразу, что ты её увеличиваешь одним запросом (я думал ты её в строку устанавливаешь) — тогда всё верно, хотя я бы на твоём месте проверил, что $credits — действительно число, иначе сделать SQL-инъекцию раз плюнуть.

Не в сети

Подвал раздела