2014-09-30 20 views
13

Tôi mới sử dụng Laravel và Eloquent, vì vậy xin lỗi nếu đây là một câu hỏi hoàn toàn ngu ngốc. Tôi đã xem xét cách tạo mô hình ở cả hai tài liệu here và cũng là một hướng dẫn khác here (trong Mô hình tạo bằng phần Eloquent ORM) và tôi đã nhận thấy rằng các trường thực tế của bảng không bao giờ được đề cập, trừ khi có một cái gì đó cụ thể về họ (như có một mối quan hệ với một bảng khác, hoặc không yêu cầu chuyển nhượng hàng loạt, hoặc nếu họ cần phải được ẩn từ đầu ra JSON, vv)Các trường trong các mô hình Eloquent Laravel

Các trường này bị bỏ qua và PHP chỉ bổ sung chúng khi nó thực hiện truy vấn bằng PDO với FETCH_OBJ được bật? Nếu có, tại sao chúng tôi không đặt các trường trong mô hình một cách rõ ràng? Nó không giúp chúng ta biết được những lĩnh vực nào chúng ta có, và cũng là các IDE như PHPStorm để bật lên các trường tự động hoàn thành đúng không?

Nếu họ thực sự được yêu cầu, họ cần có cấp truy cập nào?

Cảm ơn.

Trả lời

16

Tên cột (trường) không bắt buộc trong các mô hình Eloquent. Như bạn đã chỉ ra, chỉ cần xác định các hàm xác định các mối quan hệ mà một mô hình có với những người khác. Không cần phải bao gồm chúng, vì lý do bạn đã đề cập (Laravel thực hiện select * và sau đó thêm tất cả các hàng được trả về cho đối tượng mô hình dưới dạng thuộc tính công khai). Đây là một quá trình được gọi là hydrat hóa và bạn có thể thấy chính xác những gì đang xảy ra bằng cách đào sâu vào nguồn Laravel. Dưới đây là một bản tóm tắt về những gì sẽ xảy ra:

  1. Bạn gọi (ví dụ), Users::find(123);
  2. Illuminate\Database\Eloquent\Model::find() cuộc gọi Illuminate\Database\Eloquent\Builder::find()
  3. find() cấu trúc truy vấn SELECT * FROM users WHERE id = 123 và sau đó trả về kết quả đầu tiên bằng cách gọi Illuminate\Database\Eloquent\Builder::first()
  4. first() thêm LIMIT 1 bằng cách gọi Illuminate\Database\Query\Builder::take()
  5. Sau đó, first() đặt các cột thành r etrieved (* theo mặc định) bằng cách gọi Illuminate\Database\Eloquent\Builder::get().
  6. get() trả về một Illuminate\Database\Eloquent\Collection bằng cách sử dụng giá trị trả về của Illuminate\Database\Eloquent\Builder::getModels()
  7. getModels() thực sự thực hiện các truy vấn và sau đó gọi Illuminate\Database\Eloquent\Model::newFromBuilder() cho mỗi hàng trở
  8. newFromBuilder() tạo ra một thể hiện mới của mô hình và thiết lập các cột (trường) bằng cách gọi Illuminate\Database\Eloquent\Model::setRawAttributes()

Tôi đã bỏ qua một số thứ không liên quan như tải mong muốn để đơn giản hóa quy trình, nhưng điều này về cơ bản là những gì xảy ra cho mỗi truy vấn.

Bạn thực hiện một điểm tốt khi biết các trường trước có thể hữu ích cho tự động hoàn thành. Do tính chất của setRawAttributes(), bạn hoàn toàn có thể khai báo tất cả tên cột (trường) trong mô hình của mình (chỉ cần đảm bảo chúng là công khai). Quy ước, mặc dù (và cho bạn sanity), là để bỏ qua chúng. Tuyên bố như vậy phải được để lại migration files.

Sau khi kiểm tra thêm nguồn, đó là không phải là ok để khai báo trước các trường này. Điều này là do các giá trị thuộc tính thực tế được lưu trữ trong thuộc tính $attributes và sau đó được truy cập bằng phương pháp ma thuật __get(). Vấn đề ở đây là bằng cách xác định các thuộc tính trước, bạn sẽ ngăn không cho __get() được gọi khi bạn truy cập các trường. Vì vậy, đây không phải là một lựa chọn.

Tuy nhiên, có ways to hint to editors (like PhpStorm) about the existence of properties without explicitly defining them.

+1

Cảm ơn câu trả lời chi tiết của bạn. Tiếc là tôi không thể sử dụng nó theo cùng một cách của 'fetchObject()' của PDO, nơi tôi có thể chỉ định tên lớp và nó hydrate một thể hiện của lớp cụ thể của tôi. Tôi đang thực tế bằng cách sử dụng PhpStorm, và có vẻ như các gợi ý sử dụng các thẻ phpdoc làm việc, do đó, nó là một giải pháp tốt cho sự hỗ trợ IDE thích hợp. – jbx

+0

Nếu bạn thực sự muốn chức năng đó, bạn có thể phân lớp lớp 'Eloquent', thực sự là' Illuminate \ Database \ Eloquent \ Model', (tìm trong 'app/config/app.php' cho mảng aliases và chắc chắn rằng đặt bí danh 'Eloquent' thành FQN thích hợp cho lớp con Eloquent của bạn) và định nghĩa' setRawAttributes() 'để hoạt động như thế, nhưng điều đó có thể phức tạp hơn khi sử dụng các thẻ phpdoc. –

+1

Vâng, nó sẽ trở nên quá phức tạp và vượt ra ngoài phạm vi của những gì tôi đang cố gắng đạt được. Tôi chỉ muốn có những thứ sạch sẽ và duy trì được. Phá hoại quá nhiều so với cách tiêu chuẩn cũng có thể khiến tôi trong tình huống mà tôi sẽ không thể tìm kiếm giải pháp hoặc đặt câu hỏi tại đây. Các thẻ phpdoc có vẻ tốt, chúng cũng hữu ích để chỉ ra lĩnh vực ma thuật mà mô hình có nếu mở nó thông qua một trình soạn thảo ít thông minh hơn như Notepad ++ hoặc Vi. Cảm ơn thông tin chi tiết của bạn! – jbx

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