2009-07-02 36 views
8

Tôi tự hỏi nếu có một cách hiệu quả để kết hợp các kết quả của nhiều đối tượng ActiveRecord trong Rails. Ví dụ: tôi có thể thực hiện ba cuộc gọi riêng lẻ đến ba bảng riêng lẻ và tôi muốn kết quả được kết hợp và được sắp xếp theo một cột chung.Làm cách nào để kết hợp các đối tượng ActiveRecord?

Dưới đây là một ví dụ siêu cơ bản mã mà hy vọng sẽ làm cho câu hỏi của tôi dễ dàng hơn để hiểu:

@results1 = Table1.find(:all) 
@results2 = Table2.find(:all) 
@results3 = Table3.find(:all) 

@combined_results_sorted_by_date_column = (how?) 

Theo đề nghị của người khác, đây là một giải pháp cho vấn đề.

@combined_results = @result1 + @result2 + @result3 
@combined_results.sort! {|x,y| x.date <=> y.date} 

Nếu tôi muốn sắp xếp theo ngày, nhưng Bảng 3 đề cập đến cột "created_on" là ngày?

Trả lời

2

Bạn không làm việc với "Bảng" mà là đối tượng.

Nếu bạn nghĩ về nó theo cách này, nó sẽ làm cho không có ý nghĩa phải có:

@results1 = Users.find(:all) 
@results2 = Posts.find(:all) 
@results3 = Comments.find(:all) 

Điều gì sẽ là "kết hợp" hình thức nó có nghĩa là?

Điều bạn có thể muốn là kết hợp các kết quả từ cùng một loại bằng cách sử dụng "truy vấn" khác nhau. Có phải không?

+0

Tôi có một chú thích, kết hợp nhận xét, trạng thái và cam kết cho dòng thời gian trong ứng dụng quản lý vấn đề. – dangerousdave

+0

Trong trường hợp này, tất cả họ phải trả lời một giao diện cụ thể hoặc có cách để được ánh xạ thành một. Điểm mấu chốt là suy nghĩ về nó trong điều khoản của "bảng cơ sở dữ liệu" sẽ dẫn bạn vào thiết kế kém. Tôi đã không cố gắng để ngụ ý bạn không sử dụng dữ liệu từ những nơi khác nhau, chỉ cần đặt câu hỏi như thế nào bạn tiếp cận/suy nghĩ về nó. –

0
@combined_results = @result1 + @result2 + @result3 
@combined_results.sort! {|x,y| x.date <=> y.date} 

Mặc dù đây không phải là mã hiệu quả nhất trên thế giới, nhưng đó có thể chỉ là những gì bạn cần.

Nếu một số kiểu máy không có phương pháp ngày, tôi khuyên bạn nên tạo một phương thức. Nó dễ dàng như.

def date 
    created_on 
end 
0
@results1 = Table1.find(:all) 
@results2 = Table2.find(:all) 
@results3 = Table3.find(:all) 

combined = (@results1 + @results2 + @results3).sort { |x, y| x.date <=> y.date } 
+0

Nếu tôi muốn sắp xếp theo ngày, nhưng Bảng 3 đề cập đến cột "created_on" là ngày? Cảm ơn nhiều! – Jess

+0

Bạn có thể giải quyết điều đó bằng cách thêm phương thức "date()" vào Bảng 3 trả về giá trị của "created_on". – Ethan

14
@results1 = Table1.find(:all) 
@results2 = Table2.find(:all) 
@results3 = Table3.find(:all) 

@combined_results_sorted_by_date_column = 
    (@results1 + @results2 + @results3).sort_by(&:date) 

gì nếu tôi muốn sắp xếp theo ngày, nhưng Table3 đề cập đến cột "created_on" như ngày?

class Table3 
    alias_method :date, :created_on 
end 

hoặc đơn giản là

class Table3 
    alias date created_on 
end 
0

Tôi không chắc chắn những gì khối lượng dữ liệu của bạn là như thế, nhưng khi nói đến việc phân loại, cơ sở dữ liệu của bạn sẽ làm một công việc tốt hơn của nó hơn bao giờ bạn sẽ sử dụng " lớp ứng dụng "mã.

Bạn có cần dữ liệu được trả về dưới dạng một mảng các đối tượng mô hình khi thấy ba bảng có thể sẽ tạo ra một mảng hỗn hợp gồm ba lớp mô hình riêng biệt?

Tại sao không sử dụng các hàng và cột trả về SQL trực tiếp và DB có thực hiện tất cả công việc khó khăn để phân loại dữ liệu không?

1

Có thể bạn sẽ không thích câu trả lời này, nhưng tôi sẽ nói bạn có thể muốn sửa đổi giản đồ cơ sở dữ liệu của mình. Tôi đã ở trong một tình huống tương tự, và phân loại các kết quả sau khi nối chúng chắc chắn không phải là cách bạn muốn đi.

+1

Tôi tin bạn, nhưng bạn có thể cụ thể hơn về cách bạn xử lý tình huống này không? – iterion

0

Tôi giả sử bạn muốn có một mảng hỗn hợp gồm ba loại đối tượng ActiveRecord khác nhau, được sắp xếp theo một ngày nào đó.

@array = (Bucket.all + Mop.all + Detergent.all).sort{|x,y| x.sort_by <==> y.sort_by} 

Vì trường sắp xếp của bạn khác nhau cho từng loại đối tượng, bạn cần phải xác định trường đó.

class Bucket < ActiverRecord::Base 
    def sort_by 
    cleaned_on 
    end 
end 

class Detergent < ActiverRecord::Base 
    def sort_by 
    purchased_on 
    end 
end 

Bạn có thể lấy tất cả dữ liệu được sắp xếp trong một truy vấn bằng UNION, nhưng bạn sẽ không nhận được đối tượng AR trong số đó.

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