2010-01-12 4 views
9

Tôi tự hỏi mức độ nào tôi có thể sử dụng các liên kết trong Rails. Đi vào xem xét những điều sau đây:đường ray has_many: thông qua has_many: thông qua

class User < ActiveRecord::Base 
    has_one :provider 
    has_many :businesses, :through => :provider 
end 

class Provider < ActiveRecord::Base 
    has_many :businesses 
    has_many :bids, :through => :businesses 
    belongs_to :user 
end 

class Business < ActiveRecord::Base 
    has_many :bids 
    belongs_to :provider 
end 

class Bid < ActiveRecord::Base 
    belongs_to :business 
end 

tôi có thể thiết lập các phím tắt tiện lợi như User.businessesProvider.bids nhưng những gì về làm một cái gì đó giống như User.bids? Có thể liên kết một hiệp hội, để nói không?

Trả lời

5

Điều này hoàn toàn có thể, nhưng cần thêm một chút công việc. Các định nghĩa mô hình sau đây sử dụng kết hợp với các nested_has_many plugin bạn có thể lấy tất cả chào giá thuộc về một người dùng với chỉ @user.bids

class User < ActiveRecord::Base 
    has_one :provider 
    has_many :businesses, :through => :provider 
    has_many :bids, :through => :businesses 
end 

class Provider < ActiveRecord::Base 
    has_many :businesses 
    has_many :bids, :through => :businesses 
    belongs_to :user 
end 

class Business < ActiveRecord::Base 
    has_many :bids 
    belongs_to :provider 
end 

class Bid < ActiveRecord::Base 
    belongs_to :business 
end 

Tuy nhiên nhận được một người sử dụng từ một nỗ lực sẽ mất một công việc nhiều hơn.

+2

Có thể, nhưng cần phải cẩn thận về việc bạn làm tổ sâu sắc như thế nào, bởi vì bạn có thể làm hỏng cơ sở dữ liệu và ứng dụng đường ray của bạn. Điều đó đang được nói, tôi đã viết một bài đăng blog chi tiết cách sử dụng nested_has_many_through để làm điều này: http://kconrails.com/2010/01/28/nesting-has_many-through-relationships-in-ruby-on-rails/ –

2

Mặc dù đó là một điều rất hữu ích để có, bạn không thể có_many: thông qua mối quan hệ has_many: thông qua. Đây là giới hạn của công cụ kết nối.

Các lựa chọn thay thế là sử dụng lựa chọn phụ thông minh, hoặc trong trường hợp này là chọn phụ, hoặc cố ý không chuẩn hóa các bảng đủ để giảm độ sâu tham gia.

Ví dụ: vì Doanh nghiệp được xác định trong ngữ cảnh của Nhà cung cấp, nên lý do là bất kỳ yếu tố giá thầu nào cũng được gán, gián tiếp cho Nhà cung cấp. Việc tạo liên kết trực tiếp giữa Giá thầu và Nhà cung cấp sẽ làm cho giá thầu truy vấn trực tiếp dễ dàng.

0

Có gì ngăn cản bạn làm điều gì đó như afaik này là:

class User < ActiveRecord::Base 
    has_one :provider 
    has_many :businesses, :through => :provider 

    def bids 
     user_bids = [] 
     businesses.each |business| do 
      user_bids += business.bids 
     end 
     user_bids 
    end 
end 

class Provider < ActiveRecord::Base 
    has_many :businesses 
    has_many :bids, :through => :businesses 
    belongs_to :user 
end 

class Business < ActiveRecord::Base 
    has_many :bids 
    belongs_to :provider 
end 

class Bid < ActiveRecord::Base 
    belongs_to :business 
end 

Sau đó gọi @ user.bids nên tạo ra kết quả mong muốn, bạn cũng có thể bộ nhớ cache hồ sơ dự thầu và làm công cụ ưa thích khác nếu bạn muốn.

+0

Làm cách nào để 'giá thầu' được lưu trong bộ nhớ cache vì nó là dữ liệu không tĩnh? Làm cách nào để chúng tôi biết cập nhật bộ nhớ cache? –

4

Nếu bạn chỉ muốn tìm nạp bản ghi, tại sao không sử dụng #delegate? Nó hoạt động tốt, ít nhất là trong kịch bản bạn đã mô tả.

class User < ActiveRecord::Base 
    has_one :provider 
    delegates :bids, :to => :provider 
end 

class Provider < ActiveRecord::Base 
    has_many :businesses 
    has_many :bids, :through => :businesses 
    belongs_to :user 
end 

class Business < ActiveRecord::Base 
    has_many :bids 
    belongs_to :provider 
end 

class Bid < ActiveRecord::Base 
    belongs_to :business 
end 

Mặc dù trong không-để-khiêm tốn-Theo tôi bạn chỉ nên chuỗi các phương pháp vì nó đơn giản hơn, và bạn không còn đạt được hiệu suất tăng, trừ khi bạn đi với một số SQL tùy chỉnh điên như tadman nói.