views:

35

answers:

3

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 these 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?

A: 
@accounts = Account.find(:all, :include => :legacy_account)

or Rails3 join style

@accounts = Account.all.joins(:legacy_account)
nicholasklick
No, this doesn't seem to work. I think :include/.joins only work for models that have an association. These two models have no association. I'd simply like to combine them into a single find and view.
Callmeed
+1  A: 

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.

Terry Lorber
I ended up doing a mix of Karl's answer and this answer. I gave this one the solution because I like having it wrapped in a class.
Callmeed
+3  A: 

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.

Karl