Module: Content::ItemFinderClassMethods

Included in:
Item
Defined in:
lib/content/item_finder_class_methods.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *arguments) {|obj| ... } ⇒ Object

Yields:

  • (obj)


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/content/item_finder_class_methods.rb', line 138

def method_missing(name, *arguments, &block)
  name_s = name.to_s
  if name_s =~ /^find_all(_by)?_(.+)$/
    obj = polymorphic_finder :all, $2, arguments
  elsif name_s =~ /^find_by_(.+)$/
    obj = polymorphic_finder :first, $1, arguments
  elsif name_s =~ /^find_last(_by)?_(.+)$/
    obj = polymorphic_finder :last, $2, arguments
  elsif name_s =~ /^find_or_create_by_(.+)$/
    obj = polymorphic_finder :first, $1, arguments
    if obj.nil?
      self.create(arguments, &block)
    end
  elsif name_s =~ /^paginate_by_(.+)$/
    obj = polymorphic_pager $1, arguments
  else
    obj = super
  end
  yield(obj) if !obj.nil? and block_given?
  obj
end

Instance Method Details

#allObject



118
119
120
121
122
123
124
# File 'lib/content/item_finder_class_methods.rb', line 118

def all
  if name == "Content::Item"
    find :all
  else
    find_all_by_content_type name
  end
end

#count(options) ⇒ Object



93
94
95
# File 'lib/content/item_finder_class_methods.rb', line 93

def count(options)
  connection.count(self, options)
end

#find(*args) ⇒ Object

Find operates with four different retrieval approaches:

  • Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). If no record can be found for all of the listed ids, then RecordNotFound will be raised.

  • Find first - This will return the first record matched by the options used. These options can either be specific conditions or merely an order. If no record can be matched, nil is returned. Use Model.find(:first, *args) or its shortcut Model.first(*args).

  • Find last - This will return the last record matched by the options used. These options can either be specific conditions or merely an order. If no record can be matched, nil is returned. Use Model.find(:last, *args) or its shortcut Model.last(*args).

  • Find all - This will return all the records matched by the options used. If no records are found, an empty array is returned. Use Model.find(:all, *args) or its shortcut Model.all(*args).

All approaches accept an options hash as their last parameter.

Parameters

  • :conditions - An SQL fragment like “administrator = 1”, [ "user_name = ?", username ], or ["user_name = :user_name", { :user_name => user_name }]. See conditions in the intro.

  • :order - An SQL fragment like “created_at DESC, name”.

  • :limit - An integer determining the limit on the number of rows that should be returned.

  • :offset - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.

  • :select - By default, this is “*” as in “SELECT * FROM”, but can be changed if you, for example, want to do a join but not include the joined columns. Takes a string with the SELECT SQL fragment (e.g. “id, name”).

Examples

# find by id
Person.find(1)       # returns the object for ID = 1
Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
Person.find([1])     # returns an array for the object with ID = 1
Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")

Note that returned records may not be in the same order as the ids you provide since database rows are unordered. Give an explicit :order to ensure the results are sorted.

Examples

# find first
Person.find(:first) # returns the first object fetched by SELECT * FROM people
Person.find(:first, :conditions => [ "user_name = ?", user_name])
Person.find(:first, :conditions => [ "user_name = :u", { :u => user_name }])
Person.find(:first, :order => "created_on DESC", :offset => 5)

# find last
Person.find(:last) # returns the last object fetched by SELECT * FROM people
Person.find(:last, :conditions => [ "user_name = ?", user_name])
Person.find(:last, :order => "created_on DESC", :offset => 5)

# find all
Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people
Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
Person.find(:all, :conditions => { :friends => ["Bob", "Steve", "Fred"] }
Person.find(:all, :offset => 10, :limit => 10)
Person.find(:all, :include => [ :account, :friends ])
Person.find(:all, :group => "category")


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
# File 'lib/content/item_finder_class_methods.rb', line 62

def find(*args)
  options = {}
  which = args.shift
  if which.is_a? Symbol
    given_options = args.shift
    options.merge!(given_options) unless given_options.nil?
  else
    id = which
    which = :first
    given_options = args.shift
    options.merge!(given_options) unless given_options.nil?
  end

  options[:limit] = 1 if which == :first

  if id.nil?
    wrap_result which, connection.run_query(self, options)
  elsif id.is_a? Array
    id.collect {|one_id| find_by_id one_id}.compact
  elsif options.keys.length == 0
    find_by_id id
  else
    if options.has_key? :conditions
      options[:conditions].merge!(:__id => id)
    else
      options[:conditions] = {:__id => id}
    end
    wrap_result which, connection.run_query(self, options)
  end
end

#find_by_id(id) ⇒ Object



107
108
109
# File 'lib/content/item_finder_class_methods.rb', line 107

def find_by_id(id)
  wrap_result :first, connection.get_record_by_id(self, id.to_i)
end

#find_each(options) ⇒ Object



111
112
113
114
115
116
# File 'lib/content/item_finder_class_methods.rb', line 111

def find_each(options)
  #TODO - run the query
  if block_given?
    #each ... yield(row)
  end
end

#firstObject



126
127
128
129
130
131
132
# File 'lib/content/item_finder_class_methods.rb', line 126

def first
  if name == "Content::Item"
    find :first
  else
    find_by_content_type name
  end
end

#lastObject



134
135
136
# File 'lib/content/item_finder_class_methods.rb', line 134

def last
  all.last
end

#paginate(*args) ⇒ Object



97
98
99
100
101
102
103
104
105
# File 'lib/content/item_finder_class_methods.rb', line 97

def paginate(*args)
  options = args.first.dup
  options[:conditions] = (options[:conditions] || {}).merge(:content_type => name)
  options[:limit] = (options[:per_page] || 25)
  options[:offset] = ((options[:page] || 1) - 1) * options[:limit]
  options.delete :page
  options.delete :per_page
  find(:all, options)
end