【问题标题】:How can I update data with Eloquent without id in Laravel 4如何在 Laravel 4 中使用没有 id 的 Eloquent 更新数据
【发布时间】:2013-07-01 22:24:21
【问题描述】:

当我想更新 FaqTrans 数据库时,但这个数据集有两个主键(faq_ida 和 lang)$table->primary(array('lang', 'faq_id'));。所以我不需要带有 auto_increment 的 id 列。

但是,当我使用以下代码更新数据库时,错误消息提示我没有id 列。

$faq_trans = FaqTrans::where('faq_id','=',$faq_id)->where('lang','=',$lang)->first();
$faq_trans->lang  = Input::get('lang');
$faq_trans->body  = Input::get('body');
$faq_trans->title = Input::get('title');
$faq_trans->save();

错误信息

SQLSTATE[42S22]:找不到列:1054 未知列 'id' 在 'where 子句' (SQL: 更新FAQtrans 设置body = ?, updated_at = ? 其中 id 为空)(绑定:数组(0 => 'adfadaaadfadaa', 1 => '2013-07-04 11:12:42',))

当我添加id 列时,代码运行良好...

有什么方法可以在没有 ID 列的情况下更新数据库?

【问题讨论】:

  • 你的模型中是否设置了主键
  • 我尝试在模型中设置主键,但似乎无法同时设置两个主键(复合键),如protected $primaryKey = array('lang''faq_id');
  • 您可能必须使用->update(array('column' => 'value')) 而不是使用保存。
  • ->update(array) 不适合我,我只能使用save() 并且文档也使用save() 来更新数据..
  • 你试过只设置一个主键

标签: php laravel laravel-4 eloquent


【解决方案1】:

将此行写入您的模型

public $primaryKey = '_id';

_id 是您的手动主键

【讨论】:

    【解决方案2】:

    很简单:

    FaqTrans::where(
                [
                    'faq_id' => $faq_id,
                    'lang' => $lang
                ]
            )->update(
                [
                    'body' => $body,
                    'title' => $title
                ]
            );
    

    【讨论】:

    • 又好又简单...!
    【解决方案3】:

    Laravel / Eloquent 不支持复合主键。

    查看 Eloquent Model 类可以看到,主键只能是字符串,用于创建 WHERE 子句。

    【讨论】:

      【解决方案4】:

      对于将来偶然发现这个问题的任何人(就像我一样),这是 Eloquent 中复合主键的一个很好的解决方法。

      这位于模型类的顶部:

      protected $primaryKey = array('key1', 'key2');
      

      然后你用这个覆盖模型上的save() 方法:

      public function save(array $options = array())
      {
          if(!is_array($this->getKeyName()))
              return parent::save($options);
      
          // Fire Event for others to hook
          if($this->fireModelEvent('saving') === false)
              return false;
      
          // Prepare query for inserting or updating
          $query = $this->newQueryWithoutScopes();
      
          // Perform Update
          if ($this->exists) {
              if (count($this->getDirty()) > 0) {
                  // Fire Event for others to hook
                  if ($this->fireModelEvent('updating') === false)
                      return false;
      
                  // Touch the timestamps
                  if ($this->timestamps)
                      $this->updateTimestamps();
      
                  //
                  // START FIX
                  //
      
                  // Convert primary key into an array if it's a single value
                  $primary = (count($this->getKeyName()) > 1) ? $this->getKeyName() : [$this->getKeyName()];
      
                  // Fetch the primary key(s) values before any changes
                  $unique = array_intersect_key($this->original, array_flip($primary));
      
                  // Fetch the primary key(s) values after any changes
                  $unique = !empty($unique) ? $unique : array_intersect_key($this->getAttributes(), array_flip($primary));
      
                  // Fetch the element of the array if the array contains only a single element
                  $unique = (count($unique) <> 1) ? $unique : reset($unique);
      
                  // Apply SQL logic
                  $query->where($unique);
      
                  //
                  // END FIX
                  //
      
                  // Update the records
                  $query->update($this->getDirty());
      
                  // Fire an event for hooking into
                  $this->fireModelEvent('updated', false);
              }
      
          // Perform Insert
          } else {
              // Fire an event for hooking into
              if ($this->fireModelEvent('creating') === false)
                  return false;
      
              // Touch the timestamps
              if ($this->timestamps)
                  $this->updateTimestamps();
      
              // Retrieve the attributes
              $attributes = $this->attributes;
      
              if ($this->incrementing && !is_array($this->getKeyName()))
                  $this->insertAndSetId($query, $attributes);
              else
                  $query->insert($attributes);
      
              // Set exists to true in case someone tries to update it during an event
              $this->exists = true;
      
              // Fire an event for hooking into
              $this->fireModelEvent('created', false);
          }
      
          // Fires an event
          $this->fireModelEvent('saved', false);
      
          // Sync
          $this->original = $this->attributes;
      
          // Touches all relations
          if (array_get($options, 'touch', true))
              $this->touchOwners();
      
          return true;
      }
      

      原文来源:https://github.com/laravel/framework/issues/5517#issuecomment-52996610

      2016-05-03 更新

      我最喜欢的新方法:

      How I can put composite keys in models in Laravel 5?

      【讨论】:

      • 这在 Laravel 8.x.x 中不起作用,因为它会通过错误提示:需要字符串提供数组。
      【解决方案5】:

      转到您的 FaqTrans 模型并添加它。

      public $key = 'faq_id';
      

      应该这样做,假设faq_idlang 更重要

      【讨论】:

      【解决方案6】:

      如果有人有同样的问题。 我使用了 Nishchit Dhanani 的回答,效果很好: 将此行写入您的模型
      公共 $primaryKey = '_id';
      其中 _id 是您的手动主键

      对于我来说。我有一个用户表,我的部分用户是学生。所以我的学生表中的主键是“user_id”。
      在我的学生模型中添加这一行:public $primaryKey = 'user_id';

      我可以在更新学生对象时使用 save() 方法。

      希望对你有帮助

      【讨论】:

      • 只需为您认为有帮助的答案投票,而不是写其他答案来重复它们。
      猜你喜欢
      • 1970-01-01
      • 2021-08-28
      • 2016-02-06
      • 2013-10-05
      • 1970-01-01
      • 2013-01-30
      • 2021-03-30
      • 2012-08-29
      • 2012-08-08
      相关资源
      最近更新 更多