【问题标题】:Rails Postgres Schema Issue - One of the following schema(s) is invalid: "test" "public"Rails Postgres 架构问题 - 以下架构之一无效:“test”“public”
【发布时间】:2016-09-14 15:19:31
【问题描述】:

我已经到处搜索了这个问题的答案,但我做不到。

我正在尝试使用基于 Postgres 模式的 Rails 4、Devise 和 Apartment 构建多租户应用程序。对于我本地的 Postgres 服务器,我决定使用 PostgresApp。我关注了Go Rails multi-tenant guide,当这个错误开始出现时,我的设置(每个租户一个用户)正在工作。昨天当我尝试为 Devise 安装 Invitable 扩展时,这开始在本地显示,我似乎找不到任何关于发生了什么的线索。

这是我得到具体错误的方式:

michael$ rake environment db:drop
michael$ rake db:create
michael$ rake db:migrate
== 20160908204559 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0091s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0032s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0031s
-- add_index(:users, :confirmation_token, {:unique=>true})
   -> 0.0032s
-- add_index(:users, :unlock_token, {:unique=>true})
   -> 0.0029s
== 20160908204559 DeviseCreateUsers: migrated (0.0219s) =======================

    [WARNING] - The list of tenants to migrate appears to be empty. This could mean a few things:

      1. You may not have created any, in which case you can ignore this message
      2. You've run `apartment:migrate` directly without loading the Rails environment
        * `apartment:migrate` is now deprecated. Tenants will automatically be migrated with `db:migrate`

    Note that your tenants currently haven't been migrated. You'll need to run `db:migrate` to rectify this.
michael$ rake db:seed
Seeding test tenant
One of the following schema(s) is invalid: "test" "public"

在本地访问该站点时,这会导致 Rails 抛出:

Apartment::TenantNotFound

以下架构之一无效:“www”“public”

这是我的 apartment.rb 初始化器:

require 'apartment/elevators/subdomain'
Apartment.configure do |config|
  config.excluded_models = %w{ User }
  config.tenant_names = lambda { User.pluck :subdomain }
  config.use_schemas = true
end
Rails.application.config.middleware.use 'Apartment::Elevators::Subdomain'

这是我的用户迁移文件:

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      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

      ## Confirmable
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      t.string   :unlock_token # Only if unlock strategy is :email or :both
      t.datetime :locked_at

      ## Invitable
      #t.string   :invitation_token
      #t.datetime :invitation_created_at
      #t.datetime :invitation_sent_at
      #t.datetime :invitation_accepted_at
      #t.integer  :invitation_limit
      #t.integer  :invited_by_id
      #t.string   :invited_by_type

      ## User Info
      t.string :first_name
      t.string :last_name
      t.string :subdomain
      t.string :role

      t.timestamps
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    add_index :users, :confirmation_token,   unique: true
    add_index :users, :unlock_token,         unique: true
    #add_index :users, :invitation_token,     unique: true
  end
end

我还通过命令行进入了本地 Postrgres 数据库。下降工作,创建数据库工作。如果需要,我可以提供这些。我目前的猜测是告诉我 Rails 与 PostgresApp 对话的方式或我进行迁移的方式有问题。但也许有更多经验的人可以指出我错过的一些东西。

所以我的问题是我在做什么来导致这种情况?我该如何解决?我怎样才能更多地了解问题所在?

【问题讨论】:

    标签: ruby-on-rails postgresql devise apartment-gem postgresapp


    【解决方案1】:

    我遇到了类似的错误。我的问题是我有一个现有的应用程序,我正在尝试在该应用程序上实现 Apartment Gem。

    我通过在我的 rails 控制台中回顾性地创建每个模式来解决这个错误,例如

    Company.all.each do |c| 
      Apartment::Tenant.create(c.subdomain)
    end
    

    注意确保子域较低,例如'测试子域'

    【讨论】:

      【解决方案2】:

      好的,所以我终于修好了。当我迁移时,模式之间似乎存在差异。由于某种原因,架构没有被更新。我不完全确定为什么这解决了这个问题,但我所做的是进入租户类文件和迁移文件(在我的例子中是 User.rb),然后注释掉除设计所需的最低限度之外的所有内容。然后我一次跑一个:

      rake db:drop
      rake db:create 
      rake db:migrate
      

      在迁移过程中,出现错误:

      重复键值违反唯一约束“index_users_on_email”

      然后我返回并取消注释所有内容并重新运行 rake,这次包括 rake db:seed。它奏效了!

      michael$ rake db:seed
      Seeding test tenant
      michael$ 
      

      关于为什么会抛出这个错误,我最好的猜测是:

      1. 旧的数据库架构在两次删除之间以某种方式持续存在
      2. 新的 schema.rb 文件没有被更新并且有一个 以某种方式存在差异

      无论如何,这似乎是完美的风暴场景。如果我可以重新创建它,我会回帖。如果这种情况发生在其他人身上,则只关注模式而不是数据库、单元或设计。这应该可以为您节省大量时间。我希望这对其他人有帮助。

      【讨论】:

        【解决方案3】:

        Apartment 正在寻找一个子域:www.site.com。因此,您必须从子域的可用名称列表中排除。

        Apartment::TenantNotFound

        以下架构之一无效:“www”“public”

        您需要添加到initializers/apartment

        Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
        

        一个奖励如果你想要主域路由器

        routers.rb
        

        这将限制主要 www.site.com 或 site.com

        的路由 url
        class RootDomain
          @subdomains = ["www"]
          def self.matches?(request)
           @subdomains.include?(request.subdomain) || request.subdomain.blank?
          end
        end
        
        constraints(RootDomain) do
          your resources for the main domain only. 
        end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-14
          • 1970-01-01
          • 2015-08-03
          • 2010-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多