Ruby on rails 在rails 3.2中合并多个模型,以便用户可以使用Desive在多个子域下登录

Ruby on rails 在rails 3.2中合并多个模型,以便用户可以使用Desive在多个子域下登录,ruby-on-rails,postgresql,devise,ruby-on-rails-3.2,Ruby On Rails,Postgresql,Devise,Ruby On Rails 3.2,我正在使用Desive进行身份验证,我的用户与他们可以登录的子域相关联的方式让我感到困惑。我研究了plataformatec提供的信息以及Dave Kenedy关于Ruby Source的精彩文章。不过,我仍然不太了解联接和查询,因此无法实现这一功能 class User < ActiveRecord::Base has_many :residences ... end class Residence < ActiveRecord::Base belongs_to :u

我正在使用Desive进行身份验证,我的用户与他们可以登录的子域相关联的方式让我感到困惑。我研究了plataformatec提供的信息以及Dave Kenedy关于Ruby Source的精彩文章。不过,我仍然不太了解联接和查询,因此无法实现这一功能

class User < ActiveRecord::Base
  has_many :residences
  ...
end

class Residence < ActiveRecord::Base
  belongs_to :user
  belongs_to :apartment
  ...
end

class Apartment < ActiveRecord::Base
  has_many :residences
  belongs_to :building
  ...
end

class Building < ActiveRecord::Base
  attr_accessible :subdomain
  has_many :apartments
  ...
end
app/models/user.rb
中,我将默认的设计方法“self.find\u for\u authentication”替换为:

def self.find_for_authentication(conditions={})
  conditions[:residences] = { :subdomain => conditions.delete(:subdomain) }
  find(:first, :conditions => conditions, :joins => :residences)
end
当我运行我的规格时,我得到以下错误:

PG::Error: ERROR:  column residences.subdomain does not exist
我知道,不知何故,我必须加入我的
住宅
表,一直到
建筑
表,以确认登录的用户与具有正确子域的建筑有关联,但我不知道如何做。有人有什么想法吗?有关于连接表的信息,但这也让我感到困惑。(关于数据库和联接表的基本信息也会有所帮助。;-)

更新

我在app/models/user.rb中进行了修改

def self.find_for_authentication(conditions={})
  subdomain = conditions.delete(:subdomain)
  building = Building.find_by_subdomain(subdomain)
  apartments = Apartment.where('apartment.building_id' => building.id)
  conditions[:residences] = { :apartment_id  => apartments }
  find(:first, :conditions => conditions, :joins => :residences)
end
这可能有点接近我需要的,但我仍然在rspec中得到以下错误:

1) UserSubdomainLogins signin should not be able to signin to building without access 
 Failure/Error: click_button "Sign in"
 ActiveRecord::StatementInvalid:
   PG::Error: ERROR:  missing FROM-clause entry for table "apartment"
   LINE 1: ...SELECT "apartments"."id" FROM "apartments"  WHERE "apartment...
                                                                ^
   : SELECT  "users".* FROM "users" INNER JOIN "residences" ON "residences"."user_id" = "users"."id" WHERE "users"."email" = 'daniela@lehner.biz' AND "residences"."apartment_id" IN (SELECT "apartments"."id" FROM "apartments"  WHERE "apartment"."building_id" = 2895) ORDER BY last_name ASC LIMIT 1

在修订版中,您需要将公寓更改为公寓:

 apartments = Apartment.where('apartments.building_id' => building.id)
下面介绍了如何使用联接进行此操作:

#subdomain is already in the conditions so you don't need to do anything
def self.find_for_authentication(conditions={})
  find(:first, :conditions => conditions, 
    :joins => {:residences => {:apartment => :building }})
end
有关使用哈希的嵌套联接的更多信息,请参见以下指南中的第11.2.4节。

哪个模型有子域字段?对不起,@ShawnBalestracci,我应该更明确一些。建筑具有子域属性。谢谢,@ShawnBalestracci。这个答案可能有效,但我想我对Desive有一些问题,我必须解决。我希望在接下来的几天里实现这一点,并向大家汇报。
#subdomain is already in the conditions so you don't need to do anything
def self.find_for_authentication(conditions={})
  find(:first, :conditions => conditions, 
    :joins => {:residences => {:apartment => :building }})
end