Cool scopes with Rails 3

Blog ยป Cool scopes with Rails 3

Posted on 04 Jul 2013 15:24

Usually testing existance of associations with SQL is a hell. But rails 3 handles very difficult cases without extra gems. There is no need to use INNER OUTER JOINS, etc. If somebody wants to define the scopes below then SQL comes to mind first. I`ve searched Stack Overflow and could not find any good examples:

writers
Users who are working on a book

not in writers
Users who have not got any book

authors
Users who have at least a book published

not_in_authors
Users who have not got any book published

So here is the code:

class User
  has_many :books, dependent: :destroy,  inverse_of: :owner, foreign_key: 'owner_id'
 
  #**writers**
  #   Users who are working on a book
  def self.writers
    joins(:books).uniq
  end
 
  #**not in writers**
  #  Users who have not got any book
  def self.not_in_writers
    eager_load(:books).where(books:{id: nil}).uniq
  end
 
  #**authors**
  #   Users who have at least a book published
  def self.authors
    joins(:books).where(books: {published_date: 'NOT NULL'}).uniq
  end
 
  #**not_in_authors**
  #   Users who have not got any book published
  def self.not_in_authors
    eager_load(:books).where(books:{published_date: nil}).uniq
  end
end
 
class Book
  belongs_to :owner,  class_name: "User",  inverse_of: :books
end

Ok, writing published_date: 'NOT NULL', I cheated a bit. Nevertheless better than full SQL!

If you like this page, please spread the word: diggdel.icio.usFacebook

You can contact me if you have questions or corrections.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License