在我的项目中,我有几个模型使用了许多用于运行日常任务的范围(参见下面的缩短代码)。
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
显然,范围看起来一样,我希望通过重用范围代码来干掉一些代码。我发现这篇文章:http://hemju.com/2011/02/23/rails-3-1-release-rumors-and-news-about-features/也描述了将对象传递给范围。因此,我决定尝试一下。
/app/models/filter.rb
class Filter < Struct.new(:klass)
def call(*args); end
end
module ToCreateFilter
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
/app/models/company.rb
中的
class Company < ActiveRecord::Base
scope :to_create, Filter.new(self).extend(ToCreateFilter)
end
我称之为:
Company.to_create(start_time,end_time)
但是,此范围无法返回正确的记录数(只返回表中的所有记录)。试图追踪错误来源并没有产生任何结果。在ToCreateFilter中使用print语句证明执行到达目的地并生成正确的sql。
有什么想法吗?任何帮助表示赞赏。
答案 0 :(得分:2)
可能更好地定义像这样的模块
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
然后简单地将它包含在AR模型中?