【问题标题】:Setting the scope on a model for the rest of a request为请求的其余部分设置模型的范围
【发布时间】:2009-06-28 22:16:43
【问题描述】:

我想知道是否有办法在模型类上为请求的其余部分设置范围? IE。我想缩小一些结果的范围,但我想在主 restful 控制器不知道的情况下执行此操作(可能在注入控制器的 before_filter 中)。

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

稍后

Contacts.all

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

干杯,

布兰登

【问题讨论】:

  • 你至少试过了吗?还是你先问? :)
  • 我在询问后尝试过,因为它看起来像一个doozie。很高兴看到我可以毫不费力地想出其他人的建议:)

标签: ruby-on-rails activerecord scope


【解决方案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

【讨论】:

  • 谢谢,我最终选择了类似的东西。出于兴趣,我会在下面发布。
【解决方案2】:

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

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

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

为了减少这种可怕的错误,可以使用环绕过滤器并覆盖

Contact.default_scope(:conditions => "")

【讨论】:

  • 是的,尝试过这个,我在我的 mac 上运行开发中的乘客,所以我立即能够看到设置这样的东西的失败,因为它仍然存在于下一次调用中!事后取消设置是对的。我想如果可以证明它工作得很好,那就没问题了,但是如果有一天乘客开始多线程会发生什么?可能是一场灾难:)
【解决方案3】:
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的上下文,我们可以单独通过模型找到。

还请注意,使用联系人作为示例并不是真正的用例:D

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 2011-08-16
    • 1970-01-01
    • 2015-12-16
    • 2020-08-30
    • 1970-01-01
    相关资源
    最近更新 更多