开发者

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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜