2013-11-24 18 views
10

Tôi là người mới bắt đầu ở Rails và tôi gặp sự cố với các liên kết ActiveRecords.
tôi là tạo ra dịch vụ cho thuê xe đơn giản và tôi đã thực hiện các hiệp hội sau:Đường ray thuộc_to_many

class Client < ActiveRecord::Base 
    has_many :rentals 
    has_many :bookings 
    has_many :cars, :through => :rentals 
    has_many :cars, :through => :bookings 
end 

class Rental < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_one :car 
end 

class Booking < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_one :car 
end 

Những gì tôi cần là phải có một chiếc xe thuộc nhiều việc đặt và cho thuê trong khi mỗi đặt phòng và cho thuê có thể chỉ có một chiếc xe được giao.

class Car < ActiveRecord::Base 
    # belongs_to_many :bookings 
    # belongs_to_many :rentals 
end 

Tôi nên làm như thế nào?

Trả lời

28

Nếu xe hơi có thể có nhiều đặt chỗ/thuê, nhưng đặt chỗ/cho thuê chỉ có thể có một ô tô, bạn đang xem tình huống cổ điển belongs_to/has_many. Dường như bạn đang bị vấp ngã bởi sự khác biệt giữa belongs_tohas_one - nó không phải là một ngữ pháp, nhưng một vấn đề của nơi cột khóa ngoài nằm trong cơ sở dữ liệu của bạn.

  • belongs_to: "Tôi liên quan đến chính xác một trong số này và tôi có khóa ngoại."
  • has_one: "Tôi liên quan đến chính xác một trong số này và khóa có khóa ngoại."
  • has_many: "Tôi liên quan đến nhiều trong số này và họ có khóa ngoại."

Lưu ý rằng has_onehas_many cả hàm ý có một belongs_to trên mô hình khác, vì đó là lựa chọn duy nhất mà "này" mô hình có phím nước ngoài. Cũng lưu ý rằng điều này có nghĩa là chỉ sử dụng has_one khi bạn có mối quan hệ một-một, không phải mối quan hệ một-nhiều.

Cân nhắc điều này, tôi sẽ thay thế has_one :car bằng belongs_to :car trong cả mẫu cho thuê và đặt chỗ của bạn và đặt has_many :bookingshas_many :rentals trong mẫu ô tô của bạn. Ngoài ra, hãy đảm bảo rằng các bảng rentalsbookings của bạn có cột car_id; không nên có các cột liên quan đến thuê hoặc đặt chỗ trong bảng cars của bạn.

+0

Đó là những gì tôi đã tìm ra hôm qua, nhưng tôi cần xác nhận. Cảm ơn bạn đã giải thích! – squixy

+0

Có "Tôi liên quan đến nhiều vấn đề này, và tôi có quan hệ" khóa ngoại "không? Nó là gì? Cảm ơn! – Ziggy

+2

@ Ziggy, không có tùy chọn liên quan đến mô hình lưu trữ nhiều khóa ngoại, vì điều này không thực sự có thể bằng cách sử dụng các loại cột SQL chuẩn. Nếu bạn có mối quan hệ nhiều-nhiều (ví dụ: bài đăng có nhiều thẻ và thẻ có nhiều bài đăng), nó phải được đại diện bởi mô hình thứ ba (ví dụ: Gắn thẻ) trong cấu hình ['has_many: through'] (http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association). – Grantovich

0

Bạn không thể làm thuộc_to_many. Gần nhất bạn thực sự có thể nhận được has_and_belongs_to_many, nhưng tôi không chắc chắn đó là những gì bạn muốn ở đây - trừ khi bạn có thể có nhiều xe cho thuê/đặt phòng. Kiểm tra các guide cho một lời giải thích đầy đủ.

Tôi muốn thay đổi nó lên như thế này:

class Rental < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    belongs_to :car 
end 

class Booking < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    belongs_to :car 
end 

class Car < ActiveRecord::Base 
    has_many :bookings 
    has_many :rentals 
end 

Ngoài ra, tôi không biết làm thế nào cho thuê của bạn liên quan đến việc đặt, nhưng suy nghĩ trước mắt của tôi là nên có một số mối quan hệ giữa hai, bởi vì bạn có thể không có một thuê mà không cần đặt nó, phải không?

2

Có, có một "thuộc_to_many" trong Rails, sắp xếp. Đó là một công việc nhiều hơn một chút và bạn không thể sử dụng máy phát điện với nó. Nó được gọi là một hiệp hội polymorphic.

Mặc dù bạn có thể chế tạo xe có nhiều đặt chỗ & cho thuê, bạn có thể liên kết xe bằng cách biến nó thành một đa hình như rentable_vehicle.Mã của bạn sẽ trông giống như thế này

class Car < ActiveRecord::Base 
    belongs_to :rentable_vehicle, polymorphic: true 
end 

class Rental < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_many :cars, as: :rentable_vehicle 
end 

class Booking < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_many :cars, as: :rentable_vehicle 
end