認証に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