How Do I Mix 2 Rails Models Into a Single Find?
I have two models that are not related (in the db sense) but have some common columns (Name, Email, etc.).
Class Account < ActiveRecord::Base
end
Class LegacyAccount < ActiveRecord::Base
end
For various reasons, I cannot merge thes开发者_运维知识库e into a single model or do STI. But I would like a simple view that displays all records from both models in a nice table (possibly sorted by a common field like "name").
Is it possible to do a find/query from both models? Or can I do two finds and merge the resulting arrays so they are sorted? Can I use some intermediate model to merge both?
Simplest solution is just to merge the arrays, then just use Array
sort methods of some sort:
@accounts = (LegacyAccount.all + Account.all).sort{|x,y| x.name <=> y.name}
You could probably write a custom find method in your Account
model to make this easier so you could just call Account.find_all
or something.
There is another possible solution using SQL:
@accounts = Account.find_by_sql("SELECT * FROM accounts UNION SELECT * FROM legacy_accounts")
That works in terms of pure SQL, but I'm not sure about Rails. My guess is it will treat all LegacyAccounts as if they were normal Accounts. I'm not sure what will happen if LegacyAccounts has columns that Accounts doesn't have, either.
Alternatively you can try something from here: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html
The latter 2 solutions are tricky, so I'd only try them if you have something very specific in mind.
If they can't be joined by the database, then maybe you can define a Ruby object that merges the records and returns a hash.
class AccountView
def self.find_all
accounts = []
Account.find(:all).each do |account|
accounts << {:name => account.name, ... }
end
LegacyAccount.find(:all).each do |account|
accounts << {:name => account.name, ... }
end
return accounts
end
end
Or, define attributes on AccountView
and return an array of AccountView
objects.
Just my 2 cents here is what I have used for site RSS feed:
(Model1.latest + Model2.latest).sort_by(&:created_at).reverse
@accounts = Account.find(:all, :include => :legacy_account)
or Rails3 join style
@accounts = Account.all.joins(:legacy_account)
精彩评论