在模型上为请求的其余部分设置范围

时间:2009-06-28 22:16:44

标签: ruby-on-rails activerecord scope

我想知道是否有办法在模型类上为其余的请求设置范围?即我想缩小一些结果的范围,但我想在没有主要的restful控制器知道的情况下(也许在注入控制器的before_filter中)这样做。

Contacts.scope = { :conditions => {:public => true} } if ladeda

然后在

Contacts.all

应该返回范围的联系人。这只是假装代码,有人知道这是否可能?

干杯,

布伦登

3 个答案:

答案 0 :(得分:1)

我将如何做到这一点:

class Contact < ActiveRecord::Base
  named_scope :public_only, :conditions => {:public => true}
end

class ApplicationController
  protected
  def contacts
    @_contacts ||= ladeda ? Contact.public_only  : Contact
  end
end

class ContactsController < ApplicationController
  def index
    @contacts = contacts.all
  end
end

我正在决定是否使用范围或不使用辅助方法。或者,您可以将辅助方法移动到Contact模型本身,例如:

class Contact < ActiveRecord::Base
  def self.for_index
    ladeda ? self.public_only : self
  end
end

class ContactsController < ApplicationController
  def index
    @contacts = Contact.for_index
  end
end

答案 1 :(得分:0)

我认为范围方法甚至不存在。

要使其适用于所有后续调用,请使用

Contacts.default_scope(:conditions => {:public => true})

为了使这个不那么可怕的errorprone可能使用around过滤器并用

覆盖
Contact.default_scope(:conditions => "")

答案 2 :(得分:0)

module ContactFilterExtension

  unloadable

  def in_context(context)
    if proxy_owner.context == :special_area && context != :admin
      scoped(:conditions => {:public => true})
    else
      scoped({})
    end
  end
end

然后

class ContactContainer < ActiveRecord::Base

  unloadable

    has_many :contacts, :dependent => :destroy, :order => :position, :extend => ContactFilterExtension

end

然后在控制器中:

  def index
    @contacts = @contact_container.contacts.in_context(context)
  end

当然简化了:)这也意味着你可以在那个之后链接其他范围,并且还可以从上下文构建新记录。相当整洁。

另请注意,有两个上下文,一个我们只能在控制器中知道(用户在系统中),另一个是ContactContainer的上下文,我们可以通过模型单独找到它。 / p>

另请注意,使用Contacts作为示例并非真实用例:D