marcgg
marcgg

Reputation: 66436

Query across tables with Arel

I have two tables, users and alternative_users that are exactly the same besides a few MySQL performances tweaks.

I'd like to be able to query the second table from the first model to be able to run tests without having to change my entire codebase.

This would mean able to have this query hit the alternative_users table but still return User objects. To sum it up:

users = User.select(fields).where(conditions).limit(10) # hits alternative_users

# or

users = AlternativeUser.select(fields).where(conditions).limit(10) # returns User object

Note that find_by_sql has this ability:

users = User.find_by_sql("select * from alternative_users")`

... and it works fine, but I want to avoid rewriting code and my codebase is filled with arel keywords (where, limit...) and find_by_sql just returns an array so I can't chain.

Also note that I want this behavior only for a few queries, not the entire app. Because of this I can't use table_name.

Upvotes: 0

Views: 147

Answers (1)

matthewd
matthewd

Reputation: 4420

To just change individual Relation queries, there's a method for that: from will override the FROM clause to point to whatever you like.

User.select(:name).from("alternative_users").to_a
# SELECT name FROM alternative_users;

If you want to access both tables from throughout your application, then I'd suggest doing it with subclasses:

Rename User to AbstractUser, and add:

self.abstract_class = true

Then create empty subclasses:

class User < AbstractUser
end

class AlternativeUser < AbstractUser
end

That gives you two very similar model classes (same methods etc), but keeps them separate so you know which one you're asking for (and which one an association is linked to, for example).

Upvotes: 2

Related Questions