Module: TrixyScopes

Defined in:
lib/trixy_scopes/version.rb,
lib/trixy_scopes/trixy_scopes.rb

Defined Under Namespace

Modules: Version

Class Method Summary collapse

Class Method Details

.included(klass) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/trixy_scopes/trixy_scopes.rb', line 3

def self.included(klass)
  klass.class_eval do
    return unless klass.table_exists?
    
    connection = ActiveRecord::Base.connection
    adapter    = connection.adapter_name
    
    table_name = klass.table_name
    quoted_table_name = klass.quoted_table_name
    
    named_scope :random, :order => adapter == "SQLite" ? "RANDOM()" : "RAND()"
    named_scope :order_by, lambda {|sort_by, sort_order| { :order => "#{sort_by} #{sort_order}" } }
    named_scope :inner_join, lambda { |reflection| { :joins => reflection } }
    named_scope :left_join, lambda { |reflection|
      r = klass.reflections[reflection]
      reflection_table_name = r.class_name.constantize.quoted_table_name
      reflection_primary_key = r.class_name.constantize.primary_key
      
      {
       :joins => "LEFT JOIN #{reflection_table_name} ON #{reflection_table_name}.#{reflection_primary_key} = #{table_name}.#{r.association_foreign_key}"
      }
    }
    named_scope :limit, lambda { |limit| { :limit => limit } }
    named_scope :latest, lambda { |limit| { :limit => limit, :order => "#{quoted_table_name}.`created_at` DESC" } } 
    named_scope :earliest, lambda { |limit| { :limit => limit, :order => "#{quoted_table_name}.`created_at` ASC" } }
    
    klass.columns.each do |column|
      column_name = column.name
      
      quoted_column_name = [quoted_table_name, connection.quote_column_name(column_name)].join(".")
      
      named_scope "#{column_name}_is", lambda { |value| { :conditions => { column_name => value } } }
      named_scope "#{column_name}_is_not", lambda { |value| { :conditions => ["#{quoted_column_name} != ?", value] } }
      named_scope "#{column_name}_is_nil", :conditions => { column_name => nil }
      named_scope "#{column_name}_is_not_nil", :conditions => "#{quoted_column_name} IS NOT NULL"
      
      named_scope "#{column_name.pluralize}_are", lambda { |*ids| { :conditions => { column_name => ids.flatten } } }
      named_scope "#{column_name.pluralize}_are_not", lambda { |*ids| { :conditions => ["#{quoted_column_name} NOT IN(?)", ids.flatten] } }
      
      unless column.type == :boolean
        named_scope "#{column_name}_between", lambda { |from, to| { :conditions => ["#{quoted_column_name} BETWEEN ? AND ?", from, to] } }
        named_scope "#{column_name}_not_between", lambda { |from, to| { :conditions => ["#{quoted_column_name} NOT BETWEEN ? AND ?", from, to] } }
      end
      
      unless column.type == :boolean || column.type == :text
        named_scope "#{column_name}_in", lambda { |*elements| { :conditions => { column_name => elements.flatten } } }
        named_scope "#{column_name}_not_in", lambda { |*elements| { :conditions => ["#{quoted_column_name} NOT IN(?)", elements.flatten] } }
      end
      
      if column.name == "expires_at"
        named_scope "expired", lambda { { :conditions => ["#{quoted_column_name} < ?", Time.zone.now] } }
        named_scope "valid", lambda { { :conditions => ["#{quoted_column_name} >= ?", Time.zone.now] } }
      end
              
      if column.type == :datetime
        named_scope "#{column_name}_before", lambda { |datetime| { :conditions => ["#{quoted_column_name} < ?", datetime] } }
        named_scope "#{column_name}_after", lambda { |datetime| { :conditions => ["#{quoted_column_name} > ?", datetime] } }
        
        if column_name.last(3) == "_at"
          column_name_alias = column_name.chomp("_at")
          named_scope "#{column_name_alias}_today", lambda { { :conditions => ["#{quoted_column_name} > ?", Time.zone.now.beginning_of_day] } }
          named_scope "#{column_name_alias}_yesterday", lambda { { :conditions => ["#{quoted_column_name} BETWEEN ? AND ?", Time.zone.now.yesterday.beginning_of_day, Time.zone.now.yesterday.end_of_day] } }
          
          named_scope "#{column_name_alias}_between", lambda { |from, to| { :conditions => ["#{quoted_column_name} BETWEEN ? AND ?", from, to] } }
          named_scope "not_#{column_name_alias}_between", lambda { |from, to| { :conditions => ["#{quoted_column_name} NOT BETWEEN ? AND ?", from, to] } }
          named_scope "#{column_name_alias}_before", lambda { |datetime| { :conditions => ["#{quoted_column_name} < ?", datetime] } }
          named_scope "#{column_name_alias}_after", lambda { |datetime| { :conditions => ["#{quoted_column_name} > ?", datetime] } }
          
          named_scope "#{column_name_alias}_in_last_week",  lambda { { :conditions => ["#{quoted_column_name} > ?", 1.week.ago] } }
          named_scope "#{column_name_alias}_in_last_month", lambda { { :conditions => ["#{quoted_column_name} > ?", 1.month.ago] } }
          named_scope "#{column_name_alias}_in_last_year",  lambda { { :conditions => ["#{quoted_column_name} > ?", 1.year.ago] } }
          named_scope "#{column_name_alias}_in_month",      lambda { |datetime| { :conditions => ["#{quoted_column_name} BETWEEN ? AND ?", datetime.beginning_of_month, datetime.end_of_month] } }
          named_scope "#{column_name_alias}_in_day",        lambda { |datetime| { :conditions => ["#{quoted_column_name} BETWEEN ? AND ?", datetime.beginning_of_day, datetime.end_of_day] } }

          named_scope "#{column_name_alias}_ago", lambda { |period_type, period_count| { :conditions => ["#{quoted_column_name} > ?", period_count.send(period_type).ago] } }
        end
      end
      
      if column.type == :integer || column.type == :float
        named_scope "#{column_name}_eql", lambda { |value| { :conditions => { column_name => value } } }
        named_scope "#{column_name}_gt", lambda { |value| { :conditions => ["#{quoted_column_name} > ?", value] } }
        named_scope "#{column_name}_gte", lambda { |value| { :conditions => ["#{quoted_column_name} >= ?", value] } }
        named_scope "#{column_name}_lt", lambda { |value| { :conditions => ["#{quoted_column_name} < ?", value] } }
        named_scope "#{column_name}_lte", lambda { |value| { :conditions => ["#{quoted_column_name} <= ?", value] } }
      end
      
      if column.type == :string
        named_scope "#{column_name}_starts_with", lambda { |string| { :conditions => ["#{quoted_column_name} LIKE ?", "#{string}%"] } }
        named_scope "#{column_name}_ends_with", lambda { |string| { :conditions => ["#{quoted_column_name} LIKE ?", "%#{string}"] } }
        named_scope "#{column_name}_includes", lambda { |string| { :conditions => ["#{quoted_column_name} LIKE ?", "%#{string}%"] } }
      end
      
      if column.type == :text || column.type == :string
        named_scope "#{column_name}_like", lambda { |string| { :conditions => ["#{quoted_column_name} LIKE ?", string] } }
        named_scope "#{column_name}_not_like", lambda { |string| { :conditions => ["#{quoted_column_name} NOT LIKE ?", string] } }
      end
      
      if column.type == :boolean
        named_scope "#{column_name}", :conditions => { column_name => true }
        named_scope "not_#{column_name}", :conditions => { column_name => false }
      end
    end
    
  end
end