Using Object scopes in rails 3.1
In my project, I have several models that use a number of scopes that I use to run daily tasks (see shortened code below).
class Company < ActiveRecord::Base
def self.to_create(start_time, end_time)
where(active:1).
where("created_at between ? and ?",
start_time.strftime('%F %T'),
end_time.strftime('%F %T'))
end
def self.to_update(start_time, end_time)
where(active:1).
where("updated_at between ? and ?",
start_time.strftime('%F %T'),
end_time.strftime('%F %T')).
where('updated_at > active_updated_at')
end
end
class JobPosting < ActiveRecord::Base
def self.to_create(start_time, end_time)
where(active:1).
where("created_at between ? and ?",
start_time.strftime('%F %T'),
end_time.strftime('%F %T'))
end
def self.to_update(start_time, end_time)
where(active:1).
where("updated_at between ? and ?",
start_time.strftime('%F %T'),
end_time.strftime('%F %T')).
where('updated_at > active_updated_at')
end
end
Obviously, the scopes look the same, and I want DRY up some code by reusing scope code. I found this post: http://hemju.com/2011/02/23/rails-3-1-release-rumors-and-news-about-features/ that also described passing object to scope. Thus, I decided to try it.
/app/models/filter.rb
class Filter < Struct.new(:klass)
def call(*args); end
end
module ToCreateFi开发者_如何学Pythonlter
def call(*args)
start_time = args.shift
end_time = args.shift
klass.where(active:1).where("created_at between ? and ?",
start_time,
end_time)
super(*args)
end
end
in /app/models/company.rb
class Company < ActiveRecord::Base
scope :to_create, Filter.new(self).extend(ToCreateFilter)
end
and I call it like:
Company.to_create(start_time, end_time)
However, this scope fails to return correct number of records (simply returns all records in the table). Trying to trace the source of error did not yield any results. Using print statements in ToCreateFilter proved that execution gets where intended and generates correct sql.
Any ideas? Any help appreciated.
May be better to define module like this
module ScopeForUser
def self.included(base)
base.class_eval {
# Для выборки из корзины и т.д. Другими словами где не требуется регистрация
scope :get_for, lambda { |user, session_id|
unless user.nil?
where(:user_id => user.id)
else
where(:session_id => session_id)
end
}
}
end
end
and then simple include it in AR model?
精彩评论