7

Tôi có ba lớp: Person, Position và Directory.Ghi đè toán tử ActiveRecord << trên has_many: thông qua mối quan hệ, để chấp nhận dữ liệu cho mô hình tham gia

  • Một người has_many: directories,: through =>: position.
  • Thư mục has_many: people,: through =>: position.
  • Cả người và thư mục has_many: vị trí.
  • Mô hình Vị trí, ngoài việc có id, person_id và directory_id, có một hoặc nhiều trường bổ sung (ví dụ: tiêu đề).

Điều tôi muốn làm là thêm dữ liệu vào mô hình kết nối, chẳng hạn như trường tiêu đề, mỗi khi tôi thêm người vào bộ sưu tập Directory.people. Nhà điều hành thông thường < < sẽ không cắt nó. Id est:

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
directory.people << person 

Điều này sẽ thêm người vào bộ sưu tập người của đối tượng Directory nhưng sẽ không cho phép tôi gán dữ liệu cho mô hình tham gia. Vì vậy, sau khi làm rất nhiều nghiên cứu trên trang web này, tôi thấy một cách khác để thêm người vào bộ sưu tập người và thêm dữ liệu vào vị trí liên kết Người và Directory, id est:

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
position = person.positions.build(:directory_id => directory.id, :title => "Administrative Assistant") 
position.save 

Đây là rườm rà. Một cách không kém rườm rà sẽ là:

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
position = Position.new(directory_id: directory.id, person_id: person.id, title: "Administrative Assistant") 

Một lần nữa, có vẻ như sai vì tôi muốn để có thể nhấn mạnh mối quan hệ giữa người và Directory, mà tôi tin là những gì làm cho sử dụng has_many: thông qua phù hợp.

Những gì tôi muốn để có thể làm là sử dụng toán tử < <, và chỉ cần vượt qua các dữ liệu bổ sung, ví dụ:

directory = Directory.last # Let's assume that retrieves a Directory object 
person = Person.last # Let's assume that retrieves a Person object 
directory.people << person, :position => {:title => "Administrative Assistant"} 

Tôi đã quá tải các < < nhà điều hành trong has_many tôi: thông qua tuyên bố như sau:

has_many :people, :through => :positions do 
    def << *args 
    arg = args.first 
    if arg.is_a?(Person) 
     self.push([arg]) 
    elsif arg.is_a?(Hash) 
     # Don't know what to do in here (see below) 
    else 
     raise "Invalid Value" # There's a better error to raise here, but good enough for now. 
    end 
    end 
end 

Ưu điểm của việc làm việc này là nó hoạt động tốt cú pháp, và cho phép tôi để xác gán dữ liệu vào tham gia đối tượng (một vị trí) trong khi thêm mỗi con trai với bộ sưu tập người của đối tượng Directory.

Nhưng tôi không thể làm cho nó hoạt động được vì tôi cần có thể truy cập đối tượng thư mục mà bộ sưu tập người ở bên trái của nhà điều hành < < là thuộc tính, để tạo Vị trí và lưu nó vào kho dữ liệu.

Vì vậy, câu hỏi của tôi là:

  1. Có cách nào để truy cập vào một đối tượng từ một thuộc tính của một đối tượng?
  2. Trong trường hợp khác, có cách nào khác để quá tải toán tử < < để tôi có thể dễ dàng gán dữ liệu cho mô hình nối khi thêm một đối tượng vào bộ sưu tập không?

Cảm ơn bạn rất nhiều vì sự giúp đỡ và phản hồi chu đáo của bạn. Tôi đã hacking đi này trong nửa ngày vô ích.

trả lời Nhờ PinnyM, người đã trả lời câu hỏi này, tôi đã có thể đưa ra thực hiện điều này:

module AddToPeopleAndPositionExtension 
    def << *args 
    arg = args.first 
     if arg.is_a?(Person) 
     self.push([arg]) 
     return self 
     elsif arg.is_a?(Hash) 
     directory = proxy_association.owner 
     person = arg[:person] 
     position = person.positions.build(:directory_id => directory.id, :title => arg[:position][:title]) 
     position.save 
     else 
     raise "Invalid Value" 
     end 
    end 
end 

class Directory < ActiveRecord::Base 
    # Relationships 
    has_many :positions 
    has_many :people, :through => :positions, :extend => AddToPeopleAndPositionExtension 
end 

này cho phép tôi gọi tổng đài < < theo cách tiêu chuẩn nếu tôi đã làm không quan tâm điều gì xảy ra trên mô hình tham gia, như:

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
directory.people << person 

Và tôi cũng có thể gọi nó theo cách mà các thuộc tính được chỉ định của mô hình tham gia như :

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
directory.people << {:person => person, :position => {:title => "Administrative Assistant"}} 
+0

Tôi đã thử nó với đường ray 5.1 và nó không hoạt động vì một lý do nào đó. chức năng ghi đè không được gọi là – dowi

Trả lời

11

Bạn có thể sử dụng proxy_association helper bên trong khối để có được sự liên kết và proxy_association.owner để có được những đối tượng thư mục riêng của mình. Xem here để biết thêm thông tin về điều này.

+0

Cảm ơn sự giúp đỡ của bạn. Những công việc này. Tôi sẽ cập nhật câu trả lời của mình để phản ánh việc triển khai đầy đủ, cho bất kỳ ai khác có loại câu hỏi này. –

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