-
-
Notifications
You must be signed in to change notification settings - Fork 226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multiple db/views paths #237
base: main
Are you sure you want to change the base?
Support multiple db/views paths #237
Conversation
This follows a similar pattern to how migrations are found. It enables Rails engines to define their own db/views. It finds the first entry found in the Rails.application.config.paths["db/views"]. It still assumes Rails.root/db/views when generating a migration.
I pretty much have the same use-case. Would love to see this get merged! 👍 |
Hello!! Anyone know when this PR will be merged? Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with config.paths
and there's zero public docs on it. Do you have something you can point me to for this?
Further, are there methods on Definition
that we no longer need? (path
, full_path
)?
lib/scenic/definition.rb
Outdated
def find_definition | ||
definition = views_paths.flat_map do |directory| | ||
Dir.glob("#{directory}/**/#{filename}") | ||
end.first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
end.first | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be a find, but then it would only return the directory that the view exists under. This actually resolves the first matching file that is found under each view_path directory. Plus it could be possibly be nested.
lib/scenic/definition.rb
Outdated
Dir.glob("#{directory}/**/#{filename}") | ||
end.first | ||
|
||
unless definition |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be more consistent like this:
unless definition | |
if definition.empty? |
@@ -0,0 +1 @@ | |||
SELECT text 'Hi' as greeting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SELECT text 'Hi' as greeting | |
SELECT text 'Hi' as greeting |
Rails.application.config.paths["db/views"] << fixtures_path | ||
yield | ||
ensure | ||
Rails.application.config.paths["db/views"] = original |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
def with_views_fixtures | ||
original = Rails.application.config.paths["db/views"].to_a | ||
fixtures_path = File.expand_path("../../fixtures/db_views", __FILE__) | ||
Rails.application.config.paths["db/views"] << fixtures_path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
|
||
def with_views_fixtures | ||
original = Rails.application.config.paths["db/views"].to_a | ||
fixtures_path = File.expand_path("../../fixtures/db_views", __FILE__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/ExpandPathArguments: Use expand_path('../fixtures/db_views', dir) instead of expand_path('../../fixtures/db_views', FILE).
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
@@ -52,5 +81,14 @@ module Scenic | |||
expect(definition.version).to eq "15" | |||
end | |||
end | |||
|
|||
def with_views_fixtures | |||
original = Rails.application.config.paths["db/views"].to_a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
end | ||
|
||
it "raises an error if the file is empty" do | ||
allow(File).to receive(:read).and_return("") | ||
definition = Definition.new("empty_view", 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
@@ -2,22 +2,51 @@ | |||
|
|||
module Scenic | |||
describe Definition do | |||
describe "defintion_path" do | |||
it "raises an error if file cant be found" do | |||
definition = Definition.new("not_valid", 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
@@ -2,22 +2,51 @@ | |||
|
|||
module Scenic | |||
describe Definition do | |||
describe "defintion_path" do | |||
it "raises an error if file cant be found" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
spec/scenic/definition_spec.rb
Outdated
@@ -2,22 +2,51 @@ | |||
|
|||
module Scenic | |||
describe Definition do | |||
describe "defintion_path" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
@@ -7,6 +7,8 @@ module Scenic | |||
# @see Scenic.load | |||
class Railtie < Rails::Railtie | |||
initializer "scenic.load" do | |||
Rails.application.config.paths.add("db/views") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
@@ -28,6 +40,10 @@ def version | |||
|
|||
private | |||
|
|||
def views_paths | |||
Rails.application.config.paths["db/views"].expanded |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
lib/scenic/definition.rb
Outdated
Dir.glob("#{directory}/**/#{filename}") | ||
end.first | ||
|
||
unless definition |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/IfUnlessModifier: Favor modifier unless usage when having a single-line body. Another good alternative is the usage of control flow &&/||.
|
These could probably go away. Currently they're being used in a helper for creating new views using the generator, so maybe they could instead be changed to |
expect do | ||
connection.update_view( | ||
:views, | ||
version: 1, | ||
sql_definition: "a defintion") | ||
sql_definition: "a definition") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
Layout/MultilineMethodCallBraceLayout: Closing method call brace must be on the line after the last argument when opening brace is on a separate line from the first argument.
expect { connection.update_view :views }.to raise_error( | ||
ArgumentError, | ||
/sql_definition or version must be specified/) | ||
end | ||
|
||
it "raises an error if both version and sql_defintion are provided" do | ||
it "raises an error if both version and sql_definition are provided" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
@@ -144,18 +144,18 @@ module Scenic | |||
with(:name, definition.to_sql, no_data: true) | |||
end | |||
|
|||
it "raises an error if not supplied a version or sql_defintion" do | |||
it "raises an error if not supplied a version or sql_definition" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
@@ -108,7 +108,7 @@ module Scenic | |||
end | |||
|
|||
it "updates a view from a text definition" do | |||
sql_definition = "a defintion" | |||
sql_definition = "a definition" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
expect do | ||
connection.create_view :foo, version: 1, sql_definition: "a defintion" | ||
connection.create_view :foo, version: 1, sql_definition: "a definition" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
Metrics/LineLength: Line is too long. [81/80]
@@ -43,9 +43,9 @@ module Scenic | |||
with(:views, definition_stub.to_sql) | |||
end | |||
|
|||
it "raises an error if both version and sql_defintion are provided" do | |||
it "raises an error if both version and sql_definition are provided" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
|
||
connection.create_view(:views, sql_definition: sql_definition) | ||
|
||
expect(Scenic.database).to have_received(:create_view) | ||
.with(:views, sql_definition) | ||
end | ||
|
||
it "creates version 1 of the view if neither version nor sql_defintion are provided" do | ||
it "creates version 1 of the view if neither version nor sql_definition are provided" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
Metrics/LineLength: Line is too long. [94/80]
@@ -22,15 +22,15 @@ module Scenic | |||
end | |||
|
|||
it "creates a view from a text definition" do | |||
sql_definition = "a defintion" | |||
sql_definition = "a definition" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
if content.empty? | ||
raise "Define view query in #{path} before migrating." | ||
end | ||
end | ||
end | ||
|
||
def definition_path | ||
resolve_definition || raise("Unable to locate #{filename} in #{views_paths}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Metrics/LineLength: Line is too long. [83/80]
a7817a3
to
ff5382a
Compare
Hi, really waiting for this 👍 |
Hi, would be great to have this merged! Just ran into this when trying to use scenic from engines. |
Rails 6 adds native support for multiple databases. At this point, I’m inclined to see how we would be able to work with that. |
@derekprior an alternative approach would be to make the Scenic.configure do |config|
config.root_path = MyEngine.root
end In any case, the current setup prevents the gem from being used from within Rails engines as it looks up the Would you be interested in a PR implementing the above? |
I agree with @tomasc , it would be nice to have a configuration called root_path like the one that @tomasc propose or views_path to be more specific to set the views path, i thinks this is a better approach than the one on this PR because it is more flexible than overriding a definition. @derekprior Any provisional solution on how to use scenic inside an engine without copying files? |
Long time no review on this PR. We've had a number of PRs for this feature (see view-paths ) so I think it merits further consideration. I think this is the closest to something we could accept as it supports multiple search paths. I hope to look at this closer in the next couple of weeks. |
I needed to use this in a rails engine and didn't want to have to copy db_views over for every rails app.
This makes it so the the definition is searched for in multiple paths when trying to call
to_sql
. Generator paths aren't affected. I leveraged Rails'config.paths
for configuring additionaldb/views
paths. I could change it so that the paths are apart ofScenic::Configuration
, I just thought putting it inRails.config.paths['db/views']
would pair nicely withRails.config.paths['db/migrations']
works.I'm able to make this work with a rails engine by using the following in
engine.rb