0

認証にdeviseを使用していますが、ユーザーがログインできるサブドメインに関連付けられている方法に困惑しています。私は plataformatec が提供する情報をここで調べ、Dave Kenedy による Ruby ソースに関する素晴らしい投稿をここで調べました。ただし、これを機能させるには、まだ結合とクエリを十分に理解していません。

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

config/initializers/devise.rb私は追加しました:

config.request_keys = [:subdomain]

ではapp/models/user.rb、デフォルトのデバイス メソッド `self.find_for_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

どういうわけか、サインインしているユーザーが正しいサブドメインを持つ建物に所属していることを確認するためresidenceに、テーブルにずっと参加buildingしなければならないことは知っていますが、その方法がわかりません。誰にもアイデアはありますか?Rails Docsにはテーブルの結合に関する情報がありますが、それも私を混乱させます。(データベースとテーブルの結合に関する基本情報も役立ちます。;-))

アップデート

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
4

1 に答える 1

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 を参照してください。 http://guides.rubyonrails.org/active_record_querying.html#joining-tables

于 2013-05-08T16:02:49.233 に答える