2016-03-24 35 views
21

Tôi tò mò tại sao mối quan hệ Eloquent cho hasMany có chữ ký khác với belongsToMany. Cụ thể là tên bảng tham gia tùy chỉnh-- đối với hệ thống trong đó Comment nhất định thuộc về nhiều Role s và Role nhất định sẽ có nhiều Comment s, tôi muốn lưu trữ mối quan hệ trong một bảng gọi là my_custom_join_table và có các khóa được thiết lập là comment_keyrole_key.hasMany vs dependsToMany trong laravel 5.x

return $this->belongsToMany('App\Role', 'my_custom_join_table', 'comment_key', 'role_key'); // works 

Nhưng nghịch đảo, tôi không thể xác định rằng bảng tùy chỉnh (ít nhất là các tài liệu không đề cập đến nó):

return $this->hasMany('App\Comment', 'comment_key', 'role_key'); 

Nếu tôi có một đối tượng Role rằng hasManyComments, nhưng Tôi sử dụng một tên bảng phi tiêu chuẩn để lưu trữ mối quan hệ đó, tại sao tôi có thể sử dụng bảng phi tiêu chuẩn này theo cách này chứ không phải một cách khác?

+0

Nghịch đảo của một bi-directional nhiều-nhiều mối quan hệ là nhiều-nhiều, không phải là một-nhiều. Doctrine có [bản trình bày đẹp mắt về tất cả các lệnh liên quan] (http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-bidirectional) và triển khai của họ. – bishop

+0

Các tài liệu chính thức cũng có một rất tốt đẹp viết về quan hệ Eloquent https://laravel.com/docs/5.2/eloquent-relationships – user3158900

Trả lời

64

hasMany được sử dụng trong mối quan hệ One To Many trong khi belongsToMany đề cập đến mối quan hệ Many To Many. Chúng là hai loại mối quan hệ riêng biệt và mỗi loại yêu cầu cấu trúc cơ sở dữ liệu khác nhau - do đó chúng có các tham số khác nhau.

Sự khác biệt chính là trong mối quan hệ Một đến nhiều, bạn chỉ cần hai bảng cơ sở dữ liệu tương ứng với các mô hình liên quan. Điều này là do tham chiếu đến quan hệ là được lưu trữ trên chính bảng của mô hình đó. Ví dụ, bạn có thể có một mô hình Country và một mô hình City. Một quốc gia có nhiều thành phố. Tuy nhiên, mỗi Thành phố chỉ tồn tại ở một quốc gia. Do đó, bạn sẽ lưu trữ quốc gia đó trên chính mô hình Thành phố (dưới dạng country_id hoặc một cái gì đó tương tự).

Tuy nhiên, mối quan hệ Nhiều đến Nhiều yêu cầu một bảng cơ sở dữ liệu thứ ba, được gọi là bảng tổng hợp. Bảng tổng hợp lưu trữ các tham chiếu đến cả hai mô hình và bạn có thể khai báo nó như một tham số thứ hai trong khai báo quan hệ. Ví dụ: hãy tưởng tượng bạn có mô hình City và bạn cũng có một mô hình Car. Bạn muốn có một mối quan hệ để hiển thị các loại xe ô tô mọi người lái xe trong mỗi thành phố. Vâng, ở một thành phố, mọi người sẽ lái xe nhiều loại xe khác nhau. Tuy nhiên, nếu bạn nhìn vào một loại ô tô, bạn cũng sẽ biết rằng nó có thể được điều khiển trong số nhiều thành phố khác nhau. Do đó, không thể lưu trữ city_id hoặc car_id trên một trong hai mô hình vì mỗi mô hình sẽ có nhiều hơn một mô hình. Do đó, bạn đặt các tham chiếu đó vào bảng tổng hợp.

Như một quy tắc của ngón tay cái, nếu bạn sử dụng một mối quan hệ belongsToMany, nó có thể chỉ được ghép nối với mối quan hệ khác belongsToMany và có nghĩa là bạn có một bảng pivot thứ ba. Nếu bạn sử dụng mối quan hệ hasMany, nó có thể chỉ được ghép nối với mối quan hệ belongsTo và không yêu cầu thêm bảng cơ sở dữ liệu nào.

Trong ví dụ của bạn, bạn chỉ cần tạo mối quan hệ nghịch đảo thành belongsToMany và thêm lại bảng tùy chỉnh của bạn, cùng với các phím địa phương và nước ngoài (đảo ngược thứ tự từ mô hình khác).

+1

Đơn giản, đầy đủ, hiệu quả –

+0

Giải thích rất rõ ràng và hữu ích! – Andy

+0

Giải thích hoàn hảo –

13

Cố gắng hiểu bằng văn bản và hình.

  1. One to One (hasOne) mối quan hệ:

    • Một người dùng đã (có thể có) một hồ sơ. Vì vậy, một hồ sơ thuộc về một người dùng.
  2. Một đến nhiều (hasMany):

    • Một người sử dụng có nhiều (có thể có nhiều) bài viết. Vì vậy, nhiều bài viết thuộc về một người dùng.
  3. Nhiều người đến nhiều (BelongsToMany):

    • Một Người dùng có thể thuộc về nhiều diễn đàn. Vì vậy, một diễn đàn thuộc về nhiều người dùng.

    RelationShip

+0

Trong trường hợp hasOne/dependsTo, tôi giả sử hasOne quyết định bảng nào sẽ giữ tham chiếu đến bảng có liên quan (Bảng người dùng có profile_id trong trường hợp này)? – Lunfel