Использование объектов в рельсах 3.1 - PullRequest
0 голосов
/ 20 июля 2011

В моем проекте у меня есть несколько моделей, которые используют несколько областей, которые я использую для выполнения ежедневных задач (см. Сокращенный код ниже).

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 (время начала, время окончания)

Однако эта область не может вернуть правильное количество записей (просто возвращает все записи в таблице). Попытка отследить источник ошибки не дала никаких результатов. Использование операторов печати в ToCreateFilter доказало, что выполнение выполняется там, где задумано, и генерирует правильный sql.

Есть идеи? Любая помощь приветствуется.

1 Ответ

2 голосов
/ 29 декабря 2011

Может быть лучше определить модуль следующим образом:

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?

...