C0 code coverage information
Generated on Tue Dec 04 22:06:28 -0500 2007 with rcov 0.8.0
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 #####
2 #
3 # Copyright 2007 Chris Strom, Robin Strom
4 #
5 # This file is part of EEE Code.
6 #
7 # EEE Code is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # EEE Code is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with EEE Code. If not, see <http://www.gnu.org/licenses/>.
19 #
20 class Recipe < ActiveRecord::Base
21 has_many :preparations, :dependent => :destroy, :order => "order_number"
22 has_many :ingredients, :through => :preparations do
23 def push_with_attributes(ingredient, join_attrs)
24 Preparation.send(:with_scope, :create => join_attrs) { self << ingredient }
25 end
26 end
27
28 has_many :recipe_tools, :dependent => :destroy
29 has_many :tools, :through => :recipe_tools
30
31 has_many :recipe_inspirations, :dependent => :destroy
32
33 has_many :people, :through => :recipe_inspirations, :source => :person,
34 :conditions => "recipe_inspirations.inspiration_type = 'Person'"
35
36 has_many :books, :through => :recipe_inspirations, :source => :book,
37 :conditions => "recipe_inspirations.inspiration_type = 'Book'"
38
39 has_one :successor, :class_name => "RecipeUpdate", :foreign_key => "predecessor_id", :dependent => :destroy
40 has_one :predecessor, :class_name => "RecipeUpdate", :foreign_key => "successor_id", :dependent => :destroy
41
42 belongs_to :recipe_group
43
44 belongs_to :author, :class_name => 'User'
45 require_author
46
47 has_one :image, :as => :resource
48
49 acts_as_taggable
50 acts_as_ferret({ :fields => {
51 :title => { :boost => 2 },
52 :title_for_sort => { :index => :untokenized },
53 :date => { },
54 :summary => { },
55 :description => { },
56 :ferret_ingredients => { },
57 :ferret_tags => { },
58 :ferret_serves => { },
59 :ferret_prep_time => { },
60 :ferret_cook_time => { },
61 :ferret_inactive_time => { },
62 :ferret_number_of_ingredients => { },
63 } },
64 { :analyzer => MyAnalyzer.new })
65
66
67 validates_presence_of :title, :summary, :date, :label
68
69 cattr_reader :per_page
70 @@per_page = 20
71
72 def Recipe.ferret2web
73 @@ferret2web ||= Recipe.aaf_configuration[:fields].keys.map(&:to_s).map{ |ferret|
74 web = ferret.to_s.sub(/^ferret_/, '')
75 web.gsub!(/^tags$/, 'category')
76 web == ferret ? nil : [ferret, web]
77 }.compact
78 end
79
80 def Recipe.find_by_date_and_label(date, label)
81 Recipe.find(:first, :conditions => { :date => date, :label => label })
82 end
83
84 def Recipe.exists_with_date_and_label?(date, label)
85 Recipe.exists?(:date => date, :label => label)
86 end
87
88 def Recipe.find_by_uri(uri)
89 date, label = Recipe.date_and_label_from_uri(uri)
90 Recipe.find_by_date_and_label(date, label)
91 end
92
93 def Recipe.find_by_ymdl(o)
94 return nil unless (o.include?(:year) && o.include?(:month) && o.include?(:day))
95 return nil unless (o.include?(:label))
96 date = Date.new(o[:year].to_i, o[:month].to_i, o[:day].to_i)
97 return Recipe.find_by_date_and_label(date, o[:label])
98 end
99
100 def Recipe.date_and_label_from_uri(uri)
101 parts = uri.split(/\//)
102 date = Date.new(parts[-4].to_i, parts[-3].to_i, parts[-2].to_i)
103 label = parts[-1].sub(/\.\w+$/, '')
104 [date, label]
105 end
106
107 def Recipe.exists_with_uri?(uri)
108 date, label = Recipe.date_and_label_from_uri(uri)
109 Recipe.exists_with_date_and_label?(date, label)
110 end
111
112 def Recipe.find_howto(label)
113 Recipe.find(:first, :conditions => { :howto => true, :label => label})
114 end
115
116 # http://www.railsenvy.com/2007/2/19/acts-as-ferret-tutorial
117 def Recipe.full_text_search(q, options = {})
118 return nil if q.nil? or q==""
119 default_options = {:limit => 10, :page => 1}
120 options = default_options.merge options
121
122 # get the offset based on what page we're on
123 options[:offset] = options[:limit] * (options.delete(:page).to_i-1)
124
125 # now do the query with our options
126 results = Recipe.find_by_contents(q, options)
127 return [results.total_hits, results]
128 end
129
130 def Recipe.unpublished(*attr)
131 attr = [:all] if attr.empty?
132 Recipe.with_scope(:find => { :conditions => { :published => false } }) do
133 Recipe.find(*attr)
134 end
135 end
136
137
138 def uri
139 date.to_formatted_s(:uri) + '/' + label
140 end
141
142 def replacement
143 successor && successor.successor
144 end
145
146 def has_replacement?
147 !successor.nil?
148 end
149
150 def create_replacement(replacement, description=nil)
151 self.successor = self.build_successor(:successor => replacement, :description => description)
152 replacement
153 end
154
155 alias :replacement= :create_replacement
156
157 def replacement_for
158 predecessor && predecessor.predecessor
159 end
160
161 def is_replacement?
162 !predecessor.nil?
163 end
164
165 def ferret_enabled?(is_rebuild = false)
166 @ferret_disabled.nil? && self.published? && !self.has_replacement?
167 end
168
169 # Can't do simple Recipe.find date > ? because there are many
170 # recipes made on the same day as other recipes.
171 def next
172 recipe_ids = Recipe.find(:all,
173 :select => "id",
174 :conditions => ["date >= ? and published = ?", date, true],
175 :order => "date ASC, id DESC",
176 :limit => 20)
177 next_in_id_list(recipe_ids)
178 end
179
180 def prev
181 recipe_ids = Recipe.find(:all,
182 :select => "id",
183 :conditions => ["date <= ? and published = ?", date, true],
184 :order => "date DESC, id ASC",
185 :limit => 20)
186 next_in_id_list(recipe_ids)
187 end
188
189 # Need this to be able to manipulate via update_attributes (i.e. in controller updates)
190 def tool_ids=(new_ids)
191 ids = (new_ids || []).reject(&:blank?)
192 old_ids = self.tool_ids
193
194 self.transaction do
195 RecipeTool.destroy_all({ :tool_id => old_ids - ids, :recipe_id => self.id })
196 (ids - old_ids).each do |tool_id|
197 self.recipe_tools.create!(:tool_id => tool_id)
198 end
199 end
200 end
201
202 def inspirations
203 self.people + self.books
204 end
205
206 # Need this to be able to manipulate via update_attributes (i.e. in controller updates)
207 def person_ids=(new_ids)
208 self.set_inspiration_ids('Person', new_ids)
209 end
210
211 # Need this to be able to manipulate via update_attributes (i.e. in controller updates)
212 def book_ids=(new_ids)
213 self.set_inspiration_ids('Book', new_ids)
214 end
215
216 def ferret_ingredients
217 ingredients.map(&:name).join(' ')
218 end
219
220 def ferret_tags
221 tags.map(&:name).join(' ')
222 end
223
224 def ferret_serves
225 sprintf('%03d', serves)
226 end
227
228 def ferret_prep_time
229 sprintf('%03d', prep_time)
230 end
231
232 def ferret_cook_time
233 sprintf('%03d', cook_time)
234 end
235
236 def ferret_inactive_time
237 sprintf('%03d', inactive_time)
238 end
239
240 def title_for_sort
241 title
242 end
243
244 def ferret_number_of_ingredients
245 sprintf('%03d', ingredients.count)
246 end
247
248 def alternate_preparations
249 return [] if self.recipe_group.nil?
250
251 self.recipe_group.recipes - [self]
252 end
253
254 def to_hash
255 {
256 :title => title,
257 :date => date.to_s,
258 :label => label,
259 :image => image,
260 :serves => serves,
261 :cook_time => cook_time,
262 :prep_time => prep_time,
263 :inactive_time => inactive_time,
264 :serves => serves,
265 :tags => tags.map(&:name),
266 :ingredients => ingredients.map(&:name)
267 }
268 end
269
270 def to_json
271 to_hash.to_json
272 end
273
274 protected
275 def next_in_id_list(list)
276 current_found = false
277 next_rec = list.find do |rec|
278 if current_found
279 true
280 else
281 current_found = true if (rec.id.to_i == id)
282 false
283 end
284 end
285 next_rec.nil? ? nil : Recipe.find(next_rec.id)
286 end
287
288 def set_inspiration_ids(inspiration_type, new_ids)
289 ids = (new_ids || []).reject(&:blank?)
290 old_ids = self.send("#{inspiration_type.downcase}_ids".to_sym)
291
292 self.transaction do
293 RecipeInspiration.destroy_all({:inspiration_id => old_ids - ids, :inspiration_type => inspiration_type, :recipe_id => self.id})
294 (ids - old_ids).each do |id|
295 self.recipe_inspirations.create!(:inspiration_id => id, :inspiration_type => inspiration_type)
296 end
297 end
298 end
299
300 end
Generated using the rcov code coverage analysis tool for Ruby version 0.8.0.