On Aug 31, 8:44 am, james <[email protected]> wrote:
> class Post < ActiveRecord::Base
>   scope :published, lambda {
>     where("posts.published_at IS NOT NULL AND posts.published_at
> <= ?", Time.zone.now)
>   }
> end
>
> class User < ActiveRecord::Base
>   scope :published, lambda {
>     joins(:posts).group("users.id") & Post.published
>   }
> end
>
> User.published.to_sql
>   #=> SELECT users.* FROM "users"
>   #   INNER JOIN "posts" ON "posts"."author_id" = "users"."id"
>   #   WHERE (posts.published_at IS NOT NULL AND posts.published_at <=
> '2010-02-27 02:55:45.063181')
>   #   GROUP BY users.id
>
> This is taken 
> from:http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/th...

That's actually something that Sequel doesn't have built in support
for, though it's a fairly simple if you don't mind a gross hack:

  class Post < Sequel::Model
    def_dataset_method(:published)
{exclude(:published_at=>nil).where{published_at < Time.now}.qualify}
  end

  class User < Sequel::Model
    def_dataset_method(:published)
{group(:id).qualify.join(:posts, 
:author_id=>:id).filter(Post.published.opts[:where])}
  end

  User.published.sql
  # SELECT users.* FROM users
  # INNER JOIN posts ON (posts.author_id = users.id)
  # WHERE ((posts.published_at IS NOT NULL) AND (posts.published_at <
'2010-08-31 09:26:59.383300'))
  # GROUP BY users.id

As to why Sequel doesn't support it by default, I think it's a bad
idea.  What if you alias the posts table when joining?  What if you
use "& Post.published" without joining to the posts table?

Honestly, the example they gave could be better, since (IMO) the
proper way to do things is this:

  class Post < Sequel::Model
    def_dataset_method(:published)
{exclude(:published_at=>nil).where{published_at < Time.now}}
  end

  class User < Sequel::Model
    def_dataset_method(:published)
{group(:id).qualify.join(Post.published, :author_id=>:id)}
  end

  User.published.sql
  # SELECT users.* FROM users
  # INNER JOIN (
  #   SELECT * FROM posts
  #   WHERE ((published_at IS NOT NULL) AND
  #   (published_at < '2010-08-31 09:38:13.746317'))
  # ) AS t1 ON (t1.author_id = users.id)
  # GROUP BY users.id

or maybe even better, since you aren't returning anything from related
to posts:

  class Post < Sequel::Model
    def_dataset_method(:published)
{exclude(:published_at=>nil).where{published_at < Time.now}}
  end

  class User < Sequel::Model
    def_dataset_method(:published)
{filter(:id=>Post.published.select(:author_id))}
  end

  User.published.sql
  # SELECT * FROM users
  # WHERE (id IN (
  #   SELECT author_id FROM posts
  #   WHERE ((published_at IS NOT NULL) AND
  #    (published_at < '2010-08-31 09:46:03.104467'))
  # ))

Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en.

Reply via email to