Max Williams
2009-Apr-23 14:57 UTC
Metaprogramming oddness - works in console but fails in spec
Hi folks Let''s say i have these methods, and i want to abstract them into a bit of metaprogramming, for dryness'' sake: def water_score_for(year) self.send("ratings.water.#{year}.collect(&:score).sum") end def possible_water_score_for(year) self.ratings.water.#{year}.size * 2 end def sanitation_score_for(year) self.send("ratings.sanitation.#{year}.collect(&:score).sum") end def possible_sanitation_score_for(year) self.ratings.sanitation.#{year}.size * 2 end I''m trying to do this via ''define_method'': here''s my code: #defined elsewhere #PolicyIndicator::SECTORS = ["water", "sanitation"] PolicyIndicator::SECTORS.each do |sector| self.send(:define_method, "#{sector}_score_for".to_sym) do |year| self.send("ratings").send("#{sector}").send("for_#{year}").collect(&:score).sum end self.send(:define_method, "possible_#{sector}_score_for".to_sym) do |year| self.send("ratings").send("#{sector}").send("for_#{year}").size * 2 end end Now, this works fine in the console:>> country = Country.find(:first)=> #<Country id: 1, region_id: 1, name: "Nigeria", created_at: "2009-04-21 08:39:09", updated_at: "2009-04-22 16:24:29", sanitation_coverage: 62.0, water_coverage: 45.0, hdi: 0.405497, population_millions: 46.0, child_mortality: 52.0, gdp: 13724.8>>> country.water_score_for(2009)=> 9 But when i run a spec that makes a country, makes some ratings, associates them with the country and call the method on it, i get this error back: undefined method `for_2009'' for #<Array:0xb70cd19c> (__DELEGATION__):2:in `__send__'' (__DELEGATION__):2:in `with_scope'' (__DELEGATION__):2:in `__send__'' (__DELEGATION__):2:in `with_scope'' /home/max/work/washwatch_container/washwatch/app/models/country.rb:11:in `send'' the line (country.rb:11) in question is this: self.send("ratings").send("#{sector}").send("for_#{year}").collect(&:score).sum It seems to be falling over on the named scopes on the Rating class, so i guess maybe i''m not using ''send'' int he optimal way. However, it seems to work perfectly in the console - checking my log file, the correct, optimised sql query is being called. Can anyone help? thanks max -- Posted via http://www.ruby-forum.com/.