Frage

My app is based on the subdomain. Each manager has it's own subdomain that should show only his auctions. I have:

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

If the app was accessed using a subdomain, I have a before_filter that do the following:

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

and on my Lot's default_scope, i'd like to do the following:

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

So that way wherever I'm on the website I'll just show the lots that belongs to the manager's auctions.

The problem is that I can't access @loaded_manager on the model. What's the best way for doing this?

http://railscasts.com/episodes/388-multitenancy-with-scopes?view=comments solves this issue!

War es hilfreich?

Lösung

You may store current manager in Manager model in before filter:

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

Update

As @Mik_Die noticed it is not thread safe, for thread safe solution a reader may look at railscasts - multitenancy-with-scopes (code here). There we just store current_id in Thread.

Andere Tipps

Models don't have access to controller's instance variables (and should not have - it breaks MVC principles)

Probably, using default scope in this case is bad idea. Consider using usual scope like this

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

And then in your controller

@lots = Lot.for_manager(@loaded_manager)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top