我的应用程序主要宝石:rails 4.1.1
、pg
、acts_as_tenant
和.devise
activeadmin
应用程序描述:带有子域的 saas 多租户应用程序(不使用 postgresql 模式)。
我有 2 个模型:Account
并User
带有:
- account
belongs_to :owner
用户的 class_name - 用户
belongs_to :account
也acts_as_tenant(:account)
注意:如果使用acts_as_tenant,我不确定是否需要声明belongs_to?
在公共域 (www.myapp.dev) 上,用户可以创建一个新帐户并选择自己的子域。此用户具有此特定子域/帐户的“所有者”状态。创建帐户后,用户将被重定向到自定义子域进行登录。登录后,所有者可以创建/邀请其他用户加入他的帐户。
创建帐户时,owner_id 正确保存到帐户记录。在 ActiveAdmin 中,我可以按所有者过滤我的帐户。
问题是 account_id 没有保存在用户记录中。同样在 ActiveAdmin 中,当我尝试编辑用户记录以添加帐户时,数据没有保存......</p>
我正在学习 Rails,所以请放轻松:)
我的帐户模型:
class Account < ActiveRecord::Base
RESTRICTED_SUBDOMAINS = %w(www)
belongs_to :owner, class_name: 'User'
validates :owner, presence: true
validates :name, presence: true
validates :subdomain, presence: true,
uniqueness: { case_sensitive: false },
format: { with: /\A[\w\-]+\Z/i, message: 'contains invalid characters' },
exclusion: { in: RESTRICTED_SUBDOMAINS, message: 'restricted' }
accepts_nested_attributes_for :owner
before_validation :downcase_subdomain
def self.current_id=(id)
Thread.current[:account_id] = id
end
def self.current_id
Thread.current[:account_id]
end
private
def downcase_subdomain
self.subdomain = subdomain.try(:downcase)
end
end
我的用户模型:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
belongs_to :account
acts_as_tenant(:account)
validates :lastname, presence: true, allow_nil: false
validates :firstname, presence: true, allow_nil: false
validates :password, presence: true, allow_nil: false
validates :email, presence: true, allow_nil: false #uniqueness: true,
def to_s
"#{firstname} #{lastname} (#{email})"
end
end
应用控制器:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :authenticate_user! #, :set_mailer_host
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:accept_invitation).concat([:firstname])
end
private
def current_account
@current_account ||= Account.find_by(subdomain: request.subdomain)
end
helper_method :current_account
def after_sign_out_path_for(resource_or_scope)
new_user_session_path
end
def after_invite_path_for(resource)
users_path
end
end
账户控制人:
class AccountsController < ApplicationController
skip_before_filter :authenticate_user!, only: [:new, :create]
def new
@account = Account.new
@account.build_owner
end
def create
@account = Account.new(account_params)
if @account.valid?
@account.save
redirect_to new_user_session_url(subdomain: @account.subdomain)
else
render action: 'new'
end
end
private
def account_params
params.require(:account).permit(:subdomain, :name, owner_attributes: [:lastname, :firstname, :email, :password, :password_confirmation, :account_id])
end
end
用户控制器:
class UsersController < ApplicationController
def index
@users = User.all
end
end
我的数据库架构:
ActiveRecord::Schema.define(version: 20140619202210) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "accounts", force: true do |t|
t.string "name"
t.string "subdomain"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "owner_id"
end
create_table "active_admin_comments", force: true do |t|
t.string "namespace"
t.text "body"
t.string "resource_id", null: false
t.string "resource_type", null: false
t.integer "author_id"
t.string "author_type"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id", using: :btree
add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace", using: :btree
add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id", using: :btree
create_table "admin_users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true, using: :btree
add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true, using: :btree
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "account_id"
t.string "lastname"
t.string "firstname"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end