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à:
- 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?
- 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"}}
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