Кассир Laravel с полосой, ошибка проверки статуса подписки

#laravel #laravel-5 #laravel-cashier

#laravel #laravel-5 #laravel-кассир

Вопрос:

Я получаю следующую ошибку при проверке статуса подписки с помощью:

 $user = User::where('id', '=', Auth::user()->id)->first();

if ($user->subscribed('main')) <-- error
  

Ошибка:

 ErrorException in Builder.php line 2405: Call to undefined method
     IlluminateDatabaseQueryBuilder::valid() (View: /var/www/html...

 in Builder.php line 2405
at Builder->__call('valid', array())
at Builder->valid()
at call_user_func_array(array(object(Builder), 'valid'), array()) in Builder.php line 1426
at Builder->__call('valid', array())
at Builder->valid()
at call_user_func_array(array(object(Builder), 'valid'), array()) in Relation.php line 343
at Relation->__call('valid', array()) in Billable.php line 172
at HasMany->valid() in Billable.php line 172
at User->subscribed('main') in BillingsController.php line 58
at BillingsController->index()
  

У меня не возникает никаких проблем с использованием методов $user->onGenericTrial() and $user->onTrial() в том же представлении.

Я создал новую подписку с помощью:

 $user = User::find(1);
$user->newSubscription('main', 'monthly')->create($creditCardToken);
  

Я использую Laravel 5.2 и Cashier 6.0. Я следил за документами здесь https://laravel.com/docs/5.2/billing#checking-subscription-status .

В моей пользовательской модели я использую Laravel Cashier Оплачиваемый; и использую оплачиваемый; и hasMany в моей модели подписки. Моя модель подписки имеет отношение belongsTo к пользователю

Пользовательская модель

 <?php namespace App;

use LaravelCashierBillable;

use CarbonCarbon;

class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract {

    use Authenticatable, Authorizable, CanResetPassword;

    public $incrementing = true;

    use SoftDeletes;

    use Billable;

    protected $dates = ['deleted_at'];

    protected $table = 'users';

    protected $fillable = [ ...  'stripe_id', 'card_brand', 'card_last_four', 'trial_ends_at'];


    public function subscription()
    {
        return $this->hasMany('AppSubscription');
    }

    public function getTrialEndsAtAttribute($value)
    {
        $format = $this->getDateFormat();   
        return  Carbon::createFromFormat($format, $value, 'UTC')->setTimezone(Helper::getTimezone());
    }   
  

Вот где возникает ошибка:

https://github.com/laravel/cashier/blob/6.0/src/Billable.php

 public function subscribed($subscription = 'default', $plan = null)
{
    $subscription = $this->subscription($subscription);
    if (is_null($subscription)) {
        return false;
    }
    if (is_null($plan)) {
        return $subscription->valid();
    }
    return $subscription->valid() amp;amp;
           $subscription->stripe_plan === $plan;
}
  

Решение:

Наконец-то нашел проблему! Нельзя создавать отношения между моделями пользователя и подписки. У меня были отношения hasMany в моей пользовательской модели и отношения belongsTo в модели подписки. Это была проблема.

Комментарии:

1. Можете ли вы опубликовать свою модель пользователя?

2. Готово, добавлена модель пользователя

3. @user3489502 не могли бы вы опубликовать свое решение в качестве отдельного ответа? Я думаю, что многим из нас этого не хватает в нижней части всего вашего кода.

Ответ №1:

Можете ли вы попробовать и запустить:

 $user->first()->subscribed('main');
  

Посмотрите, выдает ли это ту же ошибку, причина, по которой я спрашиваю об этом, заключается в том, что конструктор запросов Illuminate может генерировать неопределенный метод, если экземпляр полного объекта не создан.

Я не профессионал laravel, однако я сам несколько раз сталкивался с этой проблемой, позвольте мне привести вам пример того, как я преодолеваю аналогичную проблему сегодня.

Возврат $user->payments()->first()->fetchMostRecent($customArrayValues)->first();

Кроме того, что возвращает ваш $user->subscription(); or $user->subscription()->first(); , возвращает ли эта функция то, что ожидается?

Как я уже сказал, я ни в коем случае не профессионал в laravel, однако я постараюсь помочь как можно лучше, я уверен, что более продвинутые люди здесь также окажут помощь, поскольку исключения ошибок в построителе запросов могут быть проблемой в обратной стороне!

Комментарии:

1. Спасибо @Birdy, $user->first()->subscribed('main'); выдает мне ту же ошибку, которую я уже использовал first() в своем запросе при получении $user . При $user->subscription(); этом я получаю данные пользователя, но подписка пуста.

2. Сегодня потратил на это несколько часов, подумал, что это может быть проблема с RI, но, похоже, все работает так, как должно. Попробовав это $user->subscription()->first() , я получаю единственную подписку, которую я ищу, но если я это сделаю $user->subscription()->first()->subscribed('main') , я получу Call to undefined method IlluminateDatabaseQueryBuilder::subscribed() , потому что модель подписки не использует оплачиваемый признак. Теперь, если я добавлю use LaravelCashierBillable; и use Billable; в свою модель подписки, я получу true , когда я это сделаю dd($user->subscription()->first()->subscribed('main')) .

3. но это немного странный код, чтобы добраться туда, и я почти уверен, что это не было целью с Laravel / Cashier. В документации здесь говорится, что в пользовательскую модель следует добавить оплачиваемый признак.

4. Спасибо за вашу помощь! Найдено решение (см. Выше).

5. Отлично, рад, что у вас все получилось, я не мог понять проблему, когда столкнулся с чем-то подобным, и, в конце концов, это было связано с elequent, возвращающим массивы / коллекции, и тот факт, что я пытался вызвать функцию для коллекции, а не для одного пользовательского объекта, так что это было бы похоже на запуск функции на $user-> paid()-> get(); вместо $ user-> paid()-> first(); поскольку первая функция затем выдает мне первую запись в коллекции, и именно поэтому моя ошибка выдавалась, поскольку я не осознавал, что она возвращает несколько результатов, прежде чем яиспользуется -> first(); если это имеет смысл! Будьте осторожны.