2008-10-24 28 views
7

Tình huống như sau: Tôi có 2 kiểu: 'Hành động' và 'Người dùng'. Những mô hình này đề cập đến các 'hành động' và 'người dùng' của bảng, tương ứng.Tự động gia nhập bảng mà không vi phạm hành vi mặc định trong Zend Framework

Bảng tác vụ của tôi chứa cột user_id. Tại thời điểm này, tôi cần một cái nhìn tổng quan của tất cả các hành động, và những người sử dụng mà họ được giao. Khi tôi sử dụng $action->fetchAll(), tôi chỉ có ID người dùng, vì vậy tôi muốn có thể tham gia dữ liệu từ mô hình người dùng, tốt nhất là không thực hiện cuộc gọi đến findDependentRowset().

Tôi đã nghĩ đến việc tạo các phương thức tùy chỉnh fetchAll(), fetchRow()find() trong mô hình của mình, nhưng điều này sẽ phá vỡ hành vi mặc định.

Cách tốt nhất để giải quyết vấn đề này là gì? Mọi sự trợ giúp sẽ rất được trân trọng.

+0

Có gì sai với Zend_Db_Table_Row :: findDependentRowset()? –

+1

Một sự phản đối để tìmDependentRowset() và findParentRow() là nó ít hiệu quả hơn để tải các hàng liên quan đến lười biếng mỗi lần truy vấn cả hai bảng với JOIN khi bạn biết từ đầu rằng bạn cần tất cả các hàng liên quan. –

Trả lời

14

tôi thiết kế và thực hiện các bảng mối quan hệ đặc trưng trong Zend Framework.

Nhận xét đầu tiên của tôi là bạn sẽ không sử dụng findDependentRowset() anyway - bạn sẽ sử dụng findParentRow() nếu Tác vụ có tham chiếu khóa ngoài cho Người dùng.

$actionTable = new Action(); 
$actionRowset = $actionTable->fetchAll(); 
foreach ($actionRowset as $actionRow) { 
    $userRow = $actionRow->findParentRow('User'); 
} 

Edit: Trong vòng lặp, bây giờ bạn có actionRow $ và một đối tượng $ userRow. Bạn có thể viết các thay đổi về cơ sở dữ liệu thông qua một trong hai đối tượng bằng cách thay đổi các trường đối tượng và gọi save() trên đối tượng.

Bạn cũng có thể sử dụng lớp Zend_Db_Table_Select (được triển khai sau khi tôi rời khỏi dự án) để truy xuất Rowset dựa trên sự kết hợp giữa Hành động và Người dùng.

$actionTable = new Action(); 
$actionQuery = $actionTable->select() 
    ->setIntegrityCheck(false) // allows joins 
    ->from($actionTable) 
    ->join('user', 'user.id = action.user_id'); 
$joinedRowset = $actionTable->fetchAll($actionQuery); 
foreach ($joinedRowset as $joinedRow) { 
    print_r($joinedRow->toArray()); 
} 

Lưu ý rằng Rowset như vậy dựa trên truy vấn tham gia là chỉ đọc. Bạn không thể đặt giá trị trường trong đối tượng Hàng và gọi save() để đăng thay đổi về cơ sở dữ liệu.

Chỉnh sửa: Không có cách nào để tạo một tập hợp kết quả tùy ý có thể ghi được. Hãy xem xét một ví dụ đơn giản dựa trên kết quả tham gia thiết lập ở trên:

action_id action_type user_id user_name 
    1   Buy   1  Bill 
    2   Sell   1  Bill 
    3   Buy   2  Aron 
    4   Sell   2  Aron 

Tiếp theo cho dòng với action_id = 1, tôi thay đổi một trong những lĩnh vực mà đến từ các đối tượng sử dụng:

$joinedRow->user_name = 'William'; 
$joinedRow->save(); 

câu hỏi: khi tôi xem hàng tiếp theo với action_id = 2, tôi có nên xem 'Bill' hoặc 'William' không? Nếu 'William', điều này có nghĩa là việc lưu hàng 1 phải tự động cập nhật 'Bill' thành 'William' trong tất cả các hàng khác trong tập kết quả này không? Hoặc có nghĩa là save() sẽ tự động chạy lại truy vấn SQL để nhận tập kết quả được làm mới từ cơ sở dữ liệu? Điều gì sẽ xảy ra nếu truy vấn tốn nhiều thời gian?

Cũng xem xét thiết kế hướng đối tượng. Mỗi hàng là một đối tượng riêng biệt. Có thích hợp khi gọi save() trên một đối tượng có tác dụng phụ của việc thay đổi các giá trị trong một đối tượng riêng biệt (ngay cả khi chúng là một phần của cùng một bộ sưu tập đối tượng)? Điều đó có vẻ giống như một hình thức của Content Coupling với tôi.

Ví dụ trên là một truy vấn tương đối đơn giản, nhưng cũng cho phép truy vấn phức tạp hơn nhiều. Zend_Db không thể phân tích các truy vấn với ý định cho kết quả ghi được từ kết quả chỉ đọc. Đó cũng là lý do tại sao các khung nhìn MySQL không thể cập nhật được.

+0

Cảm ơn bạn, giải thích của bạn làm rõ tình hình; Tôi sẽ chỉ đơn giản là đi với một phương thức tùy chỉnh trả về một đối tượng chỉ đọc. –

+0

Vâng, đó là một giải pháp tốt. –

+0

+1 và Cảm ơn, tôi cũng đang tìm kiếm thứ như thế này. Sẽ được mát mẻ nếu ZF có một cái gì đó giống như của RoR 'tìm (: tất cả,: bao gồm)' mặc dù – Gordon

2

Bạn luôn có thể thực hiện chế độ xem trong cơ sở dữ liệu của mình để kết nối với bạn.

CREATE OR REPLACE VIEW VwAction AS 
SELECT [columns] 
    FROM action 
    LEFT JOIN user 
    ON user.id = action.user_id 

Sau đó, chỉ cần sử dụng

$vwAction->fetchAll(); 

Chỉ cần nhớ rằng quan điểm trong MySQL là Read-Only (giả sử đây là MySQL)

1

không tạo bảng xem sql là giải pháp tốt để tạo doanh? và sau một lớp bảng đơn giản để truy cập vào nó

Tôi nghĩ rằng nó tốt hơn nếu logic của bạn là trong sql hơn trong php

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