Laravel 3:使用 $this->save() 的模型函数会导致 Eloquent 更新出错


Laravel 3: Model function with $this->save() cause error with Eloquent update

我在这方面花了太长时间,它只是不起作用,所以我放弃了,而是用 Fluent 更新方法重写它。

但我想把它贴在这里,看看以前是否有其他人遇到过这种情况。

// TEST CONTROLLER
$user = User::find(29);
// This user has a related subscription but it's lacking all of the braintree data that I need 
// So as a fallback I need to make sure that if the braintree_customer_id column is empty
// then we query braintree with an email lookup for the customer
// and then fill in the missing data.
$data = $user->subscription->braintree_customer;
var_dump($data);
// SUBSCRIPTION MODEL
public function get_braintree_customer()
{
    $braintree_customer_id = $this->braintree_customer_id;
    if (empty($braintree_customer_id))
    {
        // IF THE CUSTOMER DOESN"T HAVE ID SET THEN CALL ANOTHER FUNCTION IN THE MODEL
        $data = $this->customer_from_braintree;
        return $data;
    }
    $data = Braintree_Customer::find($braintree_customer_id);
    return $data;
}
public function get_customer_from_braintree()
{
    $data = FALSE;
    $braintree_customer = Braintree_Customer::search(array(
        Braintree_CustomerSearch::email()->is($this->user->email),
        // Braintree_CustomerSearch::email()->is('bleugh@pixelapes.com'),
    ));
    if (!empty($braintree_customer->_ids))
    {
        $braintree_customer_id = $braintree_customer->_ids[0];
        $data = Braintree_Customer::find($braintree_customer_id);
        $braintree_subscription = $data->creditCards[0]->subscriptions[0];
            $this->braintree_customer_id = $data->id;
            $this->braintree_subscription_id = $braintree_subscription->id;
            $this->braintree_payment_method_token = $braintree_subscription->paymentMethodToken;
            $this->braintree_plan_id = $braintree_subscription->planId;
            $this->save();
    }
    return $data;
}}
// IF I TRY USING $this->save() I get this error
// Even though I haven't tried to create a new Subscription - just update the old one
    Unhandled Exception
    Message:
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2' for key 'PRIMARY'
    SQL: INSERT INTO `subscriptions` (`id`, `user_id`, `braintree_customer_id`, `braintree_subscription_id`, `braintree_payment_method_token`, `braintree_plan_id`, `created_at`, `updated_at`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    Bindings: array (
      0 => 2,
      1 => 29,
      2 => '6056122',
      3 => '',
      4 => '',
      5 => '',
      6 => '2013-10-15 06:32:21',
      7 => '2013-10-15 06:32:21',
    )

Location:
path'to'laravel'database'connection.php on line 263
Stack Trace:
#0 path'to'laravel'database'connection.php(183): Laravel'Database'Connection->execute('INSERT INTO `su...', Array)
#1 path'to'laravel'database'query.php(824): Laravel'Database'Connection->query('INSERT INTO `su...', Array)
#2 [internal function]: Laravel'Database'Query->insert_get_id(Array, 'id')
#3 path'to'laravel'database'eloquent'query.php(267): call_user_func_array(Array, Array)
#4 path'to'laravel'database'eloquent'model.php(402): Laravel'Database'Eloquent'Query->__call('insert_get_id', Array)
#5 path'to'laravel'database'eloquent'model.php(402): Laravel'Database'Eloquent'Query->insert_get_id(Array, 'id')
#6 path'to'application'models'subscription.php(53): Laravel'Database'Eloquent'Model->save()
#7 path'to'laravel'database'eloquent'model.php(697): Subscription->get_customer_from_braintree()
#8 path'to'application'models'subscription.php(70): Laravel'Database'Eloquent'Model->__get('customer_from_b...')
#9 path'to'laravel'database'eloquent'model.php(697): Subscription->get_braintree_customer()
#10 path'to'application'controllers'test.php(10): Laravel'Database'Eloquent'Model->__get('braintree_custo...')
#11 [internal function]: Test_Controller->action_index()
#12 path'to'laravel'routing'controller.php(325): call_user_func_array(Array, Array)
#13 path'to'laravel'routing'controller.php(285): Laravel'Routing'Controller->response('index', Array)
#14 path'to'laravel'routing'controller.php(165): Laravel'Routing'Controller->execute('index', Array)
#15 path'to'laravel'routing'route.php(153): Laravel'Routing'Controller::call('test@index', Array)
#16 path'to'laravel'routing'route.php(124): Laravel'Routing'Route->response()
#17 path'to'laravel'laravel.php(167): Laravel'Routing'Route->call()
#18 path'to'public'index.php(34): require('D:'Work'www'xam...')
#19 {main}

我已经尝试了我能想到的每一个 Eloquent 更新方法,我尝试直接在第二个模型函数中使用 set_attribute() 函数,我尝试为我要更新的每一列创建 setter 并调用这些 setter,但随后函数成功但行未更新。

但是,如果我尝试在测试控制器中手动运行 setter,它们工作正常?!

我尝试直接从控制器调用模型函数,但它仍然会导致错误。

最奇怪的是,在我的用户模型中,我之前已经完成了这种方法,我在$this上设置属性然后运行$this->save();它工作正常。

莫名其妙!

根据大卫·巴克的评论 - 我覆盖了 __construct()

我不得不从父类中拉入$attributes和$exists。

这现在有效。

public function __construct($attributes = array(), $exists = false) {
    parent::__construct($attributes, $exists); // initialize the model according to the parent class functionality.
    require_once path('app').'libraries/braintree_php/lib/Braintree.php';
    Braintree_Configuration::environment(Config::get('braintree.environment'));
    Braintree_Configuration::merchantId(Config::get('braintree.merchant_id'));
    Braintree_Configuration::publicKey(Config::get('braintree.public_key'));
    Braintree_Configuration::privateKey(Config::get('braintree.private_key'));
}