So, I have this "advanced" query (not much, really) and I would like to translate it into Ruby Active Record's syntax.
SELECT microposts.*
FROM microposts
WHERE user_id IN
( SELECT r.followed_id as uid
FROM relationships r
WHERE follower_id = 1
UNION
SELECT u.id as uid
FROM users as u
WHERE id = 1
)
ORDER BY microposts.created_at DESC
The idea was to retrieve all microposts for user 1 AND user 1 followed users in desc creation order, but I really don't know how to translate this easily using Active Record's syntax.
Any thought ?
PS : As asked here is some rails context :
I have 3 models : Microposts
, Users
, Relationships
.
Thanks.
Your query is very specific, therefore your best bet would be to write a good portion of it using SQL, or try a gem like squeel
that can help out generating very customized SQL from ActiveRecord.
Nevertheless, this should do the work with no additional gems :
user_id = ... #Get the user_id you want to test
Micropost.where("user_id IN
( SELECT r.followed_id as uid
FROM relationships r
WHERE follower_id = ? )
OR user_id = ?
", user_id, user_id).order("created_at desc")
No idea about Ruby but the SQL can be simplified to:
SELECT microposts.*
FROM microposts
WHERE user_id IN
( SELECT r.followed_id as uid
FROM relationships r
WHERE follower_id = 1
)
OR user_id = 1
ORDER BY microposts.created_at DESC
My answer will assume (since you've provided no ruby/rails-context outside of your raw SQL query) you have a User
model, a Micropost
model through relation :microposts
, and a Relationship
model through relation :following
. User
has many Micropost
and Relationship
instances related. You could do
u = User.find(1)
user.microposts + user.following.microposts
or you could move this into a method within Micropost
def self.own_and_following(user)
user.microposts + user.following.microposts
end
And call Micropost.own_and_following(User.find(1))
.
This may not be what you're looking for, but in given the above mentioned likely relations you have in your Rails application, it sounds like something similar to this should work.
I managed to do it using only where, seems a lot like a find_by_sql to me, and I don't know which one would be better :
Micropost.order('created_at DESC').
where('user_id in (select r.followed_id as uid from relationships as r where follower_id = ?) or user_id = ?', user.id, user.id)
Don't know how good this is, but it seem to be working.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.