2016-01-08 47 views
10

Tôi tìm thấy this answer về chủ đề, nhưng nó không hoạt động đối với tôi.Thay đổi Laravel created_at khi cập nhật

Vì vậy, tôi làm cho một mục trong cơ sở dữ liệu:

// Write lead to database 
$lead = Lead::create($lead_data); 

Và timestamps trông như thế này, đó là tốt:

| 2016-01-08 10:34:15 | 2016-01-08 10:34:15 | 

Nhưng sau đó tôi thực hiện một yêu cầu đến máy chủ bên ngoài, và tôi cần cập nhật hàng:

$lead->user_id = $response['user_id']; 
$lead->broker_id = $response['broker_id']; 
$lead->save(); 

và trường created_at được thay đổi:

| 2016-01-08 04:34:17 | 2016-01-08 10:34:17 | 

Làm cách nào để giải quyết vấn đề này?

EDIT

Tôi cần một giải pháp mà sẽ chỉ thay đổi hành vi mà không thả cột hoặc đặt lại di cư. Bản sửa lỗi phải được thực hiện trên cơ sở dữ liệu trực tiếp mà không cần chạm vào dữ liệu. Như được đề xuất bên dưới, tôi đã thử di chuyển sau:

$table->datetime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->change(); 

nhưng không có gì xảy ra. Trường created_at vẫn được sửa đổi khi cập nhật.

+0

Bạn tải biến $ lead trước khi cập nhật? –

+0

Biến '$ lead' được điền bằng phương thức' create', nhưng dù sao, tôi cũng cố gắng với '$ lead = Lead :: find ($ lead-> id);' sau khi viết, vấn đề vẫn tồn tại. – Skatch

Trả lời

21

Nếu bạn đang sử dụng Laravel 5.2 và sử dụng MySQL, có một chút "lỗi" được giới thiệu với dấu thời gian. Bạn có thể đọc tất cả về vấn đề trên github here. Nó phải làm với các giá trị mặc định dấu thời gian, và MySQL tự động gán các thuộc tính DEFAULT CURRENT_TIMESTAMP hoặc ON UPDATE CURRENT_TIMESTAMP trong các điều kiện nhất định.

Về cơ bản, bạn có ba tùy chọn.

  1. Cập nhật MySQL biến:

Nếu bạn đặt biến explicit_defaults_for_timestamp-TRUE, không có cột timestamp sẽ được chỉ định CURRENT_TIMESTAMP DEFAULT hoặc ON UPDATE CURRENT_TIMESTAMP tự động thuộc tính. Bạn có thể đọc thêm về biến số here.

  1. Sử dụng nullable timestamps:

Thay đổi $table->timestamps()-$table->nullableTimestamps(). Theo mặc định, lệnh $table->timestamps() tạo các trường dấu thời gian không thể rỗng. Bằng cách sử dụng $table->nullableTimestamps(), các trường dấu thời gian của bạn sẽ bị vô hiệu và MySQL sẽ không tự động gán thuộc tính đầu tiên cho thuộc tính DEFAULT CURRENT_TIMESTAMP hoặc ON UPDATE CURRENT_TIMESTAMP.

  1. Xác định timestamps mình:

Thay vì sử dụng $table->timestamps, sử dụng $table->timestamp('updated_at'); $table->timestamp('created_at'); mình. Đảm bảo rằng trường 'updated_at' của bạn là dấu thời gian đầu tiên trong bảng, do đó nó sẽ là trường tự động gán thuộc tính DEFAULT CURRENT_TIMESTAMP hoặc ON UPDATE CURRENT_TIMESTAMP.

+0

Tôi cần một giải pháp mà tôi có thể triển khai trên cơ sở dữ liệu hoạt động trực tiếp. Việc đặt lại các cột di chuyển và thả không phải là một tùy chọn. – Skatch

3

Skatch - Tôi nghĩ giải pháp của bạn ở trên không hoàn toàn đúng, nhưng probaby là tốt trong trường hợp này.

Vấn đề là bạn đang nhận được ngày PHP, không phải là dấu thời gian MYSQL mặc định cho mặc định của bạn. Khi bạn chạy di chuyển đó, bạn kết thúc bằng một tuyên bố như sau:

alter table alter column created_at default '2016:02:01 12:00:00'; 

Lưu ý chuỗi cho ngày của bạn. Khi bạn chạy di chuyển của bạn THAT ngày sẽ luôn được sử dụng cho created_at của bạn, không phải là ngày hiện tại khi một bản ghi được thêm vào ngày sau đó.

Thay vì làm "ngày ('Y: m: d H: i: s')", bạn có thể làm DB :: raw ('current_timestamp') để giải quyết vấn đề này.

(sry, không thể chỉ cần thêm một bình luận trên - uy tín của tôi là chưa đủ cao ...)

+0

Bạn nói đúng, tôi không nghĩ về điều đó. Dù sao, tôi đã thử tất cả mọi thứ, bao gồm cả đề nghị của bạn '$ table-> datetime ('created_at') -> mặc định (DB :: raw ('CURRENT_TIMESTAMP')) -> change();', nhưng đây là cách duy nhất nó làm việc ... Lần tới tôi sẽ cố gắng làm tốt hơn với SQL. – Skatch

+1

Bạn có cần thực hiện việc này thông qua di chuyển không? Các lệnh SQL bản địa là thẳng về phía trước: "thay đổi bảng mytable sửa đổi cột mycolumn dấu thời gian mặc định current_timestamp NOT NULL trên cập nhật current_timestamp;" Chạy trực tiếp trên DB và mọi thứ sẽ được khắc phục. (kiểm tra đầu tiên!). Nếu bạn PHẢI làm điều đó thông qua một di chuyển, bạn có thể làm điều đó với DB :: không chuẩn bị ($ MyRawSQL) ;. Một cái gì đó giống như chức năng công cộng lên() {Schema :: create (....); DB :: không chuẩn bị ($ MySQL); } – sgrover

+0

- Điều đó cũng bỏ qua lỗi mà @patricus đã đề cập. – sgrover

1

viết bài này như một câu trả lời cấp cao nhất, tổng kết cuộc thảo luận bình luận của chúng tôi.

Trước tiên, có một ngày bug được giới thiệu trong Laravel - như được ghi chú bởi @patricus. Các giải pháp được đề xuất trong thảo luận lỗi là sử dụng nullableTimestamps() thay vì chỉ dấu thời gian() hoặc để tạo các trường created_at và updated_at trực tiếp - $table->timestamp('updated_at')->change().

Điều này cũng có thể được khắc phục bằng SQL thô. Tuyên bố ALTER tương tự như điều này

alter table loader_rawvalues MODIFY column updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 

Điều đó có thể được áp dụng trực tiếp cho bảng DB hiện tại của bạn (Hãy thử nghiệm trước tiên hoặc khóa học!). HOẶC bạn có thể sử dụng DB :: không chuẩn bị() để áp dụng nó từ di chuyển của bạn - ví dụ:

class CreateMyTable extends Migration 
{ 
    public function up() 
    { 
     Schema::create('mytable', function (Blueprint $table) { 
      $table->bigIncrements('id'); 
      // ... 
      $table->timestamps(); 
     }); 

     DB::unprepared('alter table mytable MODIFY column updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'); 
    } 
} 
+0

Tôi nghĩ rằng bạn cần phải thay đổi trường created_at mà không có câu lệnh 'ON UPDATE', update_at hoạt động tốt.:) – Skatch

+0

Để xác nhận, nếu bạn cần chạy di chuyển để khắc phục vấn đề updated_at, dựa trên giải pháp của sgrover, bạn có thể thêm thông tin sau vào quá trình di chuyển của mình cho tất cả các bảng yêu cầu sửa lỗi mà không bị rơi: 'DB :: unprepared (' thay đổi faqs bảng sửa đổi cột created_at timestamp mặc định current_timestamp NOT NULL '); ' cùng với ' DB :: chuẩn bị (' Alter faqs bảng sửa đổi cột updated_at current_timestamp timestamp mặc định NOT NULL');' này sẽ thiết lập dấu thời gian để mặc định là CURRENT TIMESTAMP và loại bỏ quy tắc ON UPDATE phụ. –

Các vấn đề liên quan