Проблема схемы Rails Postgres - одна из следующих схем недопустима: "test" "public"

Я искал ответ на этот вопрос все выше и ниже, но у меня мало шансов.

Я пытаюсь создать мультитенантное приложение с Rails 4, Devise и Apartment на основе схем Postgres. Для моего локального сервера Postgres я решил использовать PostgresApp. Я следовал мультитенантному руководству Go Rails, и у меня была эта настройка (по одному пользователю на каждого арендатора), когда эта ошибка начала появляться. Это началось локально вчера, когда я пытался установить расширение Invitable для Devise, и я не могу найти какие-либо подсказки относительно того, что происходит.

Вот как я получаю конкретную ошибку:

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" "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 или как я делаю миграции. Но, может быть, кто-то с большим опытом может указать на то, что я пропустил.

Итак, мои вопросы, что я делаю, чтобы вызвать это? Как я могу это исправить? И как я могу узнать больше о том, что не так?

3 ответа

Решение

Итак, я наконец исправил это. Похоже, что при миграции произошли расхождения между схемами. По какой-то причине схема не обновлялась по той или иной причине. Я не совсем уверен, почему это решило проблему, но я пошел в файл класса арендатора и файл миграции (в моем случае User.rb), а затем закомментировал все, кроме минимума, необходимого для Devise. Потом я бегал по одному:

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

При переносе я получил ошибку:

двойное значение ключа нарушает уникальное ограничение "index_users_on_email"

Тогда я вернулся и все оставил без комментариев, перезапустил грабли и включил в этот раз рейк db: seed. И это сработало!

michael$ rake db:seed
Seeding test tenant
michael$ 

Мое лучшее предположение относительно того, почему эта ошибка была выброшена, было то, что:

  1. Старая схема базы данных как-то сохранялась между падениями
  2. Что новый файл schema.rb не обновлялся и что-то было несоответствующим

В любом случае, похоже, что это был идеальный сценарий шторма. Я отправлю обратно, если смогу воссоздать его. Если это происходит с кем-то еще, сосредоточьтесь исключительно на схеме, а не на базе данных, квартире или устройстве. Это должно сэкономить вам много времени. Я надеюсь, что это помогает кому-то еще.

У меня была похожая ошибка. Моя проблема заключалась в том, что у меня было приложение, в котором я пытался реализовать Apartment Gem.

Я решил эту ошибку, создав каждую схему ретроспективно в моей консоли rails, например:

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

ПРИМЕЧАНИЕ: убедитесь, что субдомены меньше, например, "testsubdomain"

Квартира ищет поддомен: www.site.com. Таким образом, вы должны исключить из списка доступных имен для поддоменов.

Квартира::TenantNotFound

Недопустима одна из следующих схем: "www" "public"

вам нужно добавить в initializers/apartment

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

бонус, если вы хотите маршрутизаторы основного домена

routers.rb

Это будет ограничивать маршруты URL для основного 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
Другие вопросы по тегам