-
-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle ActiveRecord table name prefix and suffix
ActiveRecord allows you to set `table_name_prefix` and `table_name_suffix` both via configuration (which ultimately sets the options on `ActiveRecord::Base`) and in any subclass of ActiveRecord. When set in configuration or directly on `ActiveRecord::Base`, rails migrations and the schema dumper make the setting transparent to migrations, `schema.rb`, etc. For example, if I run the following: ``` ActiveRecord::Base.table_name_prefix = "api_" class CreateUsers < ActiveRecord::Migration[7.0] def change create_table :users end end ``` then the table that is created in the database is `app_users`, but `schema.rb` calls the table `users`. If the user runs `rake db:schema:load` then the table is created as `app_users` once again. Setting the prefix or suffix in any way other than in configuration or directly on `ActiveRecord::Base` does not influence schema generation at all. Prior to this change, Scenic didn't handle this situation at all. If you had a prefix set and tried to run `create_view :searches` Scenic would fail looking for the file `app_searches_v01.sql`. It turns out, rails migrations mutate the arguments to most every method call automatically. See: https://github.com/rails/rails/blob/4607108f91881cd1c24285dca63dc8e0f3f8a4f1/activerecord/lib/active_record/migration.rb#L917-L933 To get around this, I added `Scenic::UnaffixedName` so we could reverse this process. This is essentially a copy of what Rails itself does in its own schema dumper here: https://github.com/rails/rails/blob/4607108f91881cd1c24285dca63dc8e0f3f8a4f1/activerecord/lib/active_record/schema_dumper.rb#L295-L299 By unaffixing the view name in two places, we're able to fully support table name prefix and suffix. This was probably more investigative work than was warranted for this edge case feature, but I dove in thinking it was going to be easy and now here we are... Fixes #295
- Loading branch information
1 parent
4b6264d
commit b1544dc
Showing
8 changed files
with
71 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
module Scenic | ||
# The name of a view or table according to rails. | ||
# | ||
# This removes any table name prefix or suffix that is configured via | ||
# ActiveRecord. This allows, for example, the SchemaDumper to dump a view with | ||
# its unaffixed name, consistent with how rails handles table dumping. | ||
class UnaffixedName | ||
# Gets the unaffixed name for the provided string | ||
# @return [String] | ||
# | ||
# @param name [String] The (potentially) affixed view name | ||
def self.for(name) | ||
new(name, config: ActiveRecord::Base).call | ||
end | ||
|
||
def initialize(name, config:) | ||
@name = name | ||
@config = config | ||
end | ||
|
||
def call | ||
prefix = Regexp.escape(config.table_name_prefix) | ||
suffix = Regexp.escape(config.table_name_suffix) | ||
name.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1") | ||
end | ||
|
||
private | ||
|
||
attr_reader :name, :config | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
module RailsConfigurationHelpers | ||
def with_affixed_tables(prefix: "", suffix: "") | ||
ActiveRecord::Base.table_name_prefix = prefix | ||
ActiveRecord::Base.table_name_suffix = suffix | ||
yield | ||
ensure | ||
ActiveRecord::Base.table_name_prefix = "" | ||
ActiveRecord::Base.table_name_suffix = "" | ||
end | ||
end |