如何在rails中链接我的正常和动态范围

时间:2014-05-13 10:12:06

标签: ruby-on-rails ruby ruby-on-rails-4 model chaining

我正在尝试链接一些范围方法(instead of using an actual scope),但我在组合它们时遇到了问题。我现在有下面的代码工作,但它不完全干。 如果我能写出像

这样的东西会更好
Project.from_advertisers(advertiser_ids).active

Project.from_advertisers(advertiser_ids).finished

而不是必须使用我创建的单独方法'active_from_advertisers'和'finished_from_advertisers',您可以在下面的代码中看到。这些单独的方法有效,但上面提到的首选链式方法给出的错误是第一个是数组......

是否有可能在模型中以某种方式实现这一目标?

感谢您的帮助!

#### campaign.rb
# datetime   :start_on
# datetime   :end_on
# integer    :advertiser_id
class Campaign < ActiveRecord::Base
  belongs_to :project
  belongs_to :advertiser

  def self.active
    self.select{|c| c.end_on >= Time.now && c.start_on <= Time.now }
  end

  def self.finished
    self.select{|c| c.end_on <= Time.now }
  end
end

#### project.rb
class Project < ActiveRecord::Base
  has_many :campaigns

  def self.active
    includes(:campaigns).joins(:campaigns).select{|p| p.end_on >= Time.now && p.start_on <= Time.now }
  end

  def self.finished
    includes(:campaigns).joins(:campaigns).select{|p| p.end_on && p.end_on <= Time.now }
  end

  def self.from_advertisers(advertiser_ids)
    includes(:campaigns).joins(:campaigns).select{|p| advertiser_ids.include?(p.advertiser_id)}
  end

  def self.active_from_advertisers(advertiser_ids)
    includes(:campaigns).select{|p| advertiser_ids.include?(p.advertiser_id) && p.end_on >= Time.now && p.start_on <= Time.now }
  end

  def self.finished_from_advertisers(advertiser_ids)
    includes(:campaigns).select{|p| advertiser_ids.include?(p.advertiser_id) && p.end_on && p.end_on <= Time.now }
  end

  def advertiser_id
    campaigns.first.try(:advertiser_id)
  end

  def start_on
    campaigns.map(&:start_on).min
  end

  def end_on
    campaigns.map(&:end_on).max
  end
end

1 个答案:

答案 0 :(得分:2)

使用.select将始终返回一个数组。

您可以考虑使用where方法更改查询。

def self.active
    where("end_on >= #{Time.now} && start_on <= #{Time.now}")
end