Rails Arel and Active Record predicates
I might be lacking some understanding concerning Arel objects in Rails.
You can do something like:
u = User.arel_table
then and crazy query additions like:
u.join(:microposts)
(implicit .on(users[:user_id]) ).
But how do 开发者_运维问答you convert an Arel relation to a list of Rails objects?
Update
A better example is this. I just finished Michael Hartl's Rails tutorial where he does something similar to this in the Micropost controller:
followed_ids = %(SELECT followed_id FROM relationships WHERE follower_id = :user_id)
where("user_id in (#{followed_ids}) OR user_id = :user_id", :user_id => user)
I hate the raw SQL. So I want to refactor, so far the best I have is this:
followed_ids = Relationship.select(:followed_id).where(:follower_id => user)
where("user_id in (#{followed_ids.to_sql}) OR user_id = :user_id", :user_id => user)
I used to add .map(&:followed_id).join(", ") to the Relationship select which also works but then you have all ids in memory instead of a short select statement for the db to process.
My issue is that it seemed that I needed to do a .to_sql to feed to where and make it happy, when it has everything it needs to return me my objects. I am thinking of switching to Squeel which can do the subquery nicely but I want to understand Arel.
Well you can do
User.joins(User.arel_table.joins(:microposts))
But there's not much point in that since you can just do User.joins(:microposts)
and get the same result. But if you have to create some more complex joins it could be handy.
Something like this can be useful though.
User.where(User.arel_table[:name].matches('John%'))
And remember while you can take advantage of some of the core Arel stuff in Rails, it's often better to stick to the simpler methods like .where(:name=>'John')
or .where('name LIKE ?', 'John%')
since Rails will turn them into Arel objects behind the scenes anyway.
精彩评论