with_scope with scope
http://errtheblog.com/posts/39-withscope-with-scope
class Movie < ActiveRecord::Base def self.with_playing with_scope :find => { :conditions => [ ‘state = ? AND visible = ?’, NOW_PLAYING, true ] } do yield end end end
class MovieController < ApplicationController def director Movie.with_playing do @director = Movie.find_by_id(params[:movie_id]).director end end end
Not bad, but I do like having find_playing handle the yielding for me to keep my controllers slim. What about this:
class Movie < ActiveRecord::Base def self.find_playing(*args) with_playing do find(*args) end end def self.find_playing_by_id with_playing do find_by_id(*args) end end def self.with_playing with_scope :find => { :conditions => [ ‘state = ? AND visible = ?’, NOW_PLAYING, true ] } do yield end end end
That works, but if I do Dan’s with_playing in the controller I get access to all the find_by_* methods—not just ones I hardcode. That’s cool, and I want that in my model. So let’s add some method_missing into my find_playing lifestyle:
def self.method_missing(method, *args, &block) if method.to_s =~ /^find_(all_)?playing_by/ with_playing do super(method.to_s.sub('playing_', ''), *args, &block) end else super(method, *args, &block) end end
# This will give us find_playing_by_blah and find_all_playing_by_jlah. Tricky.
Нет комментариев »
RSS лента комментариев Трэкбэк