Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Config apartment-gem for MySQL using structure.sql instead of schema.rb to create a new tenant

I need View SQL and Stored Procedure in my Rails app so I have to change from schema.rb to structure.sql. This is my config in config/application.rb

config.active_record.schema_format = :sql

but then when I create a new record for an entity in seed.rb

Company.create(
        name: 'Google',
        subdomain: 'google'
      )

error happened

my_project/db/schema.rb doesn't exist yet

I don't know what is the problem. Did I miss something in cofig, somewhere still require schema.rb or I miss some rake task command? I just used

rake db:migrate db:test:prepare

follow this blog https://rietta.com/blog/2013/11/28/rails-and-sql-views-for-a-report/#setting-up-the-sql-view

UPDATE: I am using apartment-gem and Company entity is a Tenant.

Here is config in apartment.rb

Apartment.configure do |config|
  config.excluded_models = %w{ Company CommonField }
  config.tenant_names = lambda{ Company.pluck(:subdomain) }
  # ==> PostgreSQL only options
  config.use_schemas = true

  # Apartment can be forced to use raw SQL dumps instead of schema.rb for 
  # creating new schemas.
  # Use this when you are using some extra features in PostgreSQL that can't 
  # be respresented in
  # schema.rb, like materialized views etc. (only applies with use_schemas set 
  # to true).
  # (Note: this option doesn't use db/structure.sql, it creates SQL dump by 
  # executing pg_dump)
  #
  # config.use_sql = false
  # <== PostgreSQL only options
  config.prepend_environment = !Rails.env.production?
end

I try to change config.use_schemas to false then enable and set config.use_sql to true but it still not work. Maybe it's setting for PosrtgreSQL only.

So, have any setting for MySQL?

like image 638
bird Avatar asked May 08 '17 02:05

bird


People also ask

How do you regenerate a schema RB?

If you run a rake -T it will list all possible rake tasks for your Rails project. One of them is db:schema:dump which will recreate the schema.

What is schema RB?

The schema. rb serves mainly two purposes: It documents the final current state of the database schema. Often, especially when you have more than a couple of migrations, it's hard to deduce the schema just from the migrations alone. With a present schema.

What is structure SQL?

structure. sql instead is a SQL representation of the database and it depends on the specific database you selected. You only use the structure if you have specific database features that you need and that can't be represented by the schema. rb . For example, in the past some people replaced schema.


1 Answers

the mysql2_adapter in gem apartment extend from abstract_adapter and it inherits the create method as below:

def create(tenant)
 run_callbacks :create do
  create_tenant(tenant)

  switch(tenant) do
   import_database_schema

   # Seed data if appropriate
   seed_data if Apartment.seed_after_create

   yield if block_given?
  end
 end
end

the import_database_schema method will throw the error: FileNotFound ... db/schema.rb doesn't exist yet if there's no such file schema.rb, so i guess when you decide to use structure.sql instead of schema.rb you deleted it.

i suggest 2 ways to fix:

  1. create an empty file schema.rb, that it.
  2. you still need the config use_schemas since that indicate gem apartment will use postgresql schemas and mysql use, however in case of mysql, if you use structure.sql, no need to import_database_schema at all, right ? so you can create new mysql adapter like below:
# your-app/lib/apartment/adapters/mysql2_structure_adapter.rb
require 'apartment/adapters/mysql2_adapter'

module Apartment
  module Tenant
    def self.mysql2_adapter(config)
      if Apartment.use_schemas
        Apartment.use_sql ?
          Adapters::Mysql2StructureAdapter.new(config) :
          Adapters::Mysql2SchemaAdapter.new(config)
      else
        Adapters::Mysql2Adapter.new(config)
      end
    end
  end

  module Adapters
    class Mysql2StructureAdapter < Mysql2SchemaAdapter
      def create(tenant)
        run_callbacks :create do
          create_tenant(tenant)

          switch(tenant) do
            # no need to import schema
            # import_database_schema

            # Seed data if appropriate
            seed_data if Apartment.seed_after_create

            yield if block_given?
          end
        end
      end
    end
  end
end

then load that adapter, also turn on both use_schemas and use_sql on initializer config

# config/initializers/apartment.rb
Apartment.configure do |config|
  # ...
  config.use_schemas = true
  config.use_sql = true
end
# ...
Dir[File.join(Rails.root, "lib", "apartment", "adapters", "**/*.rb")].each {|r| require r}
like image 196
Lam Phan Avatar answered Oct 06 '22 16:10

Lam Phan