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 |
derekprior
left a comment
There was a problem hiding this comment.
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)?
| def find_definition | ||
| definition = views_paths.flat_map do |directory| | ||
| Dir.glob("#{directory}/**/#{filename}") | ||
| end.first |
There was a problem hiding this comment.
| end.first | |
| end |
There was a problem hiding this comment.
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.
| Dir.glob("#{directory}/**/#{filename}") | ||
| end.first | ||
|
|
||
| unless definition |
There was a problem hiding this comment.
This would be more consistent like this:
| unless definition | |
| if definition.empty? |
| @@ -0,0 +1 @@ | |||
| SELECT text 'Hi' as greeting No newline at end of file | |||
There was a problem hiding this comment.
| 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.
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.
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.
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.
| end | ||
|
|
||
| def with_views_fixtures | ||
| original = Rails.application.config.paths["db/views"].to_a |
There was a problem hiding this comment.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
|
|
||
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
|
|
||
| module Scenic | ||
| describe Definition do | ||
| describe "defintion_path" do |
There was a problem hiding this comment.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| # @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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| private | ||
|
|
||
| def views_paths | ||
| Rails.application.config.paths["db/views"].expanded |
There was a problem hiding this comment.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| Dir.glob("#{directory}/**/#{filename}") | ||
| end.first | ||
|
|
||
| unless definition |
There was a problem hiding this comment.
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 |
| :views, | ||
| version: 1, | ||
| sql_definition: "a defintion") | ||
| sql_definition: "a definition") |
There was a problem hiding this comment.
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.
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
|
|
||
| it "updates a view from a text definition" do | ||
| sql_definition = "a defintion" | ||
| sql_definition = "a definition" |
There was a problem hiding this comment.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| it "raises an error if both version and sql_definition are provided" do | ||
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
Metrics/LineLength: Line is too long. [81/80]
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| 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.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
Metrics/LineLength: Line is too long. [94/80]
|
|
||
| it "creates a view from a text definition" do | ||
| sql_definition = "a defintion" | ||
| sql_definition = "a definition" |
There was a problem hiding this comment.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
| end | ||
|
|
||
| def definition_path | ||
| resolve_definition || raise("Unable to locate #{filename} in #{views_paths}") |
There was a problem hiding this comment.
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
endIn 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.pathsfor configuring additionaldb/viewspaths. 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