开发者

How to turn a self-table subquery SQL to a Rails named_scope?

开发者 https://www.devze.com 2023-02-24 16:27 出处:网络
I\'m using rails 2.3.10 and new to named_scope. I\'m dealing with a SQL which retrieves a list of last invitations of a particular event. I came up with a SQL with subquery and it looks like it can do

I'm using rails 2.3.10 and new to named_scope. I'm dealing with a SQL which retrieves a list of last invitations of a particular event. I came up with a SQL with subquery and it looks like it can do what I want. I'm thinking of is it possible to use named_scope to do the same thing so that I can make use of it with find().

I have the following questions:

  1. Is it possible to implement the SQL with named_scope?
  2. Can it be in a elegant way so that the sub-select is not included in the :condition?more than one named_scope needed?
  3. How do the named_scope(s) look like?
  4. How does the find() look like when it includes the name_scope(s)?

SQL:

SELECT *
  FROM invitation inv1
  JOIN (
         SELECT event_id, user_id, MAX(invite_time) AS last_invite_time
           FROM invitation
          GROUP BY event_id, user_id
       ) AS last_invite ON
       inv1.event_id = last_invite.event_id AND
       inv1.user_id = last_invite.user_id AND
       inv1.invite_time = last_invite.last_invite_time

Invitation data:

event_id     user_id     invite_time       invite_reply_code
1            78          2011-02-01 15:21 开发者_如何学Go 1
2            78          2011-02-02 11:45  1
2            79          2011-02-02 11:50  1
2            79          2011-02-02 11:55  1
2            80          2011-02-02 11:50  1
2            80          2011-02-02 11:51  1

Expected result:

event_id     user_id     invite_time       invite_reply_code
2            78          2011-02-02 11:45  1
2            79          2011-02-02 11:55  1
2            80          2011-02-02 11:51  1


The :joins option in find can take a string, which it will just stick into the SQL. To get your event_id in there you will need to use a lambda, so something like this is what you're after:

named_scope :foo, lambda { |event_id|
  { :select => "oinv.*",
    :from => "invitation AS oinv"
    :joins => <<-SQL
      JOIN (
             SELECT event_id, user_id, MAX(invite_time) AS last_invite_time
               FROM invitation AS jinv
              GROUP BY event_id, user_id
           ) AS last_invite ON
           oinv.event_id       = last_invite.event_id AND
           oinv.user_id        = last_invite.user_id AND
           oinv.invite_time    = last_invite.last_invite_time
      SQL
    , :conditions => [ "oinv.event_id = ?", event_id ]
  }
}

This is totally untested, but hopefully you can see what I'm doing and this sets you on the right path.

0

精彩评论

暂无评论...
验证码 换一张
取 消