【问题标题】:Access Controller Variable on default_scopedefault_scope 上的访问控制器变量
【发布时间】:2013-04-21 19:03:43
【问题描述】:

我的应用基于子域。每个经理都有自己的子域,应该只显示他的拍卖。我有:

class Lot < ActiveRecord::Base
  belongs_to :auction
end

class Auction < ActiveRecord::Base
  has_many :lots
  belongs_to :manager
end

class manager < ActiveRecord::Base
  has_many :auctions
end

如果应用程序是使用子域访问的,我有一个 before_filter 执行以下操作:

def load_manager
  @loaded_manager = Manager.find_by_subdomain(request.subdomain)
end

在我的 Lot 的 default_scope 上,我想做以下事情:

  default_scope {  @loaded_manager.present? ? where(deleted: false).joins(:auction => :manager).where("auctions.manager_id = ?", @loaded_manager.id) :  where(deleted: false)  }  

这样无论我在网站上的哪个位置,我都会显示属于经理拍卖的拍品。

问题是我无法访问模型上的@loaded_manager。这样做的最佳方法是什么?

http://railscasts.com/episodes/388-multitenancy-with-scopes?view=comments 解决了这个问题!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 controller scope default-scope


    【解决方案1】:

    模型无权访问控制器的实例变量(也不应该有 - 它违反了 MVC 原则)

    可能在这种情况下使用默认范围是个坏主意。考虑使用像这样的常用范围

    scope :for_manager, lambda{ |manager| manager.present? ? where(deleted: false).joins(:auction => :manager).where("auctions.manager_id = ?", manager.id) :  where(deleted: false) }
    

    然后在你的控制器中

    @lots = Lot.for_manager(@loaded_manager)
    

    【讨论】:

      【解决方案2】:

      您可以在过滤器之前将当前经理存储在经理模型中:

      def load_manager
        Manager.set_current(request.subdomain)
      end
      
      class Manager < ActiveRecord::Base
        cattr_accessor :current
      
        def self.set_current(subdomain)
          self.current = self.find_by_subdomain(subdomain)
        end
      end
      
      class Lot < ActiveRecord::Base
        default_scope { Manager.current.present? ? where(deleted: false).joins(:auction => :manager).where("auctions.manager_id = ?", Manager.current.id) : where(deleted: false) }
      end
      

      更新

      @Mik_Die 注意到它不是线程安全的,对于线程安全的解决方案,读者可以查看railscasts - multitenancy-with-scopes (code here)。我们只是将 current_id 存储在Thread 中。

      【讨论】:

      • 让 Model 了解请求是不好的做法
      • 顺便说一句,这不是线程安全的解决方案,因为它会改变整个类的状态
      猜你喜欢
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2012-06-26
      • 2014-09-06
      • 2015-12-05
      相关资源
      最近更新 更多