Rails Postgres架构问题 - 以下架构之一无效:" test" "公共"

时间:2016-09-14 15:19:32

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

我已经高低搜索了这个答案,但我很快就出现了。

我正在尝试使用基于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抛出:

  

公寓:: TenantNotFound

     

以下架构之一无效:" www" "公共"

这是我的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数据库。 drop正在运行,create database正在运行。如果需要,我可以提供这些。我现在的猜测是告诉我,Rails如何与PostgresApp交谈或者我如何进行迁移有问题。但也许有经验丰富的人可以指出一些我错过的东西。

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

3 个答案:

答案 0 :(得分:1)

我有类似的错误。我的问题是我有一个现有的应用程序,我试图实现公寓宝石。

我通过在rails控制台中追溯创建每个模式来解决这个错误,例如。

void    *ft_memcpy(void *dst, const void *src, size_t n)
{    
        while (n--)
                *(char *)dst++ = *(char *)src++;
        return (dst);
}

注意确保子域名较低,例如&#39; testsubdomain&#39;

答案 1 :(得分:0)

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

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

在迁移时,我收到了一个错误:

  

重复键值违反了唯一约束&#34; index_users_on_email&#34;

然后我回去取消评论所有内容并重新运行耙子,这次包括rake db:seed。它有效!

michael$ rake db:seed
Seeding test tenant
michael$ 

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

  1. 旧数据库架构以某种方式在drop之间持续存在
  2. 新的schema.rb文件没有更新,而且有一个 某种程度上的差异
  3. 无论哪种方式,这似乎是完美的风暴情景。如果我可以重新创建它,我会回复。如果发生这种情况,其他人只关注架构,而不是数据库,公寓或设计。这应该可以节省你很多时间。我希望这有助于其他人。

答案 2 :(得分:0)

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

  

公寓:: TenantNotFound

     

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

您需要添加到initializers/apartment

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

奖励如果您想要主域名路由器

routers.rb

这将限制主要 www.site.com或site.com 的路线网址

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