-
Notifications
You must be signed in to change notification settings - Fork 463
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
Scope for leaves #246
base: master
Are you sure you want to change the base?
Scope for leaves #246
Conversation
15aef88
to
37e4a9b
Compare
I'd too would like to add postgres specific version of some other methods. e.g.: sorting by nulls vs using a case statement. At a hight level, is the code here the best way to introduce database specific sql? |
@kbrock I'd say if more methods start to appear then it's better to extract them into an |
392e112
to
a46a4e2
Compare
@kbrock good shout, let's see what the arel guys think. Judging by the previous PR attempt they're not very positive about supporting infix operators. |
@kbrock nice one, I never thought it would make it's way into |
Alternate is add a file in config/initializer
|
@antstorm Arel supports Ancestry 2.1.x can support older rails, just not get these newer features. |
@kbrock I'm not using |
Hi @antstorm , would you be comfortable if I rebase this PR and give it a new life, since I found it much better than mine (#388) in terms of SQL efficiency and simplicity. (@kbrock I'm assuming currently nobody is working on it, let me know if I'm in a totally wrong place.. you might already have clear ideas about what to be done.) Hope that makes sense 😸 |
@fursich sure, I've rebased it. Do you think there's anything missing from it? |
6 similar comments
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 looks good
@@ -36,5 +36,5 @@ services: | |||
- postgresql | |||
|
|||
before_script: | |||
- mysql -e 'create database ancestry_test;' || true | |||
- psql -c 'create database ancestry_test;' -U postgres || true | |||
- mysql -e 'CREATE DATABASE ancestry_test CHARACTER SET utf8 COLLATE utf8_general_ci;' || true |
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.
Hi @antstorm
I think this line is significant. Could you please explain more about this?
We may want to add this to the general documentation to help people.
Also if this is not changed as the database collation, then I wonder what users can do to get this behavior.
I'm also thinking postgres on mac has a similar issue with this.
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.
or maybe this line should be collation on just the column if they don't do this to the whole database?
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 added collation to the column and not to the whole database.
Thanks for putting this on my radar.
@@ -17,6 +17,17 @@ def scope_depth depth_options, depth | |||
end | |||
end | |||
|
|||
# Scope that returns all the leaves | |||
def leaves | |||
id_column = "#{table_name}.id" |
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.
id_column = "#{table_name}.id" | |
id_column = "#{table_name}.#{self.class.primary_key}" |
|
||
joins("LEFT JOIN #{table_name} AS c ON c.#{ancestry_column} = #{id_column_as_text} OR c.#{ancestry_column} = #{parent_ancestry}") | ||
.group(id_column) | ||
.having('COUNT(c.id) = 0') |
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.
.having('COUNT(c.id) = 0') | |
.having("COUNT(c.#{self.class.primary_key}) = 0") |
id_column_as_text = sql_cast_as_text(id_column) | ||
parent_ancestry = sql_concat("#{table_name}.#{ancestry_column}", "'/'", id_column_as_text) | ||
|
||
joins("LEFT JOIN #{table_name} AS c ON c.#{ancestry_column} = #{id_column_as_text} OR c.#{ancestry_column} = #{parent_ancestry}") |
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 looks like "children" to me.
Think we may want "subtree" instead?
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.
but it seems to be working.
Could you just give your opinion on what you think about this line and multiple levels of nested members?
Thnx
@@ -6,6 +6,9 @@ def test_scopes | |||
# Roots assertion | |||
assert_equal roots.map(&:first), model.roots.to_a | |||
|
|||
# Leaves assertion | |||
assert_equal model.all.select(&:is_childless?), model.leaves.order(:id).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.
well, this does look like it is bringing back nodes from 2 levels deep.
ASIDE (nothing to do with you or this PR):
The way the tests are organized, it sure makes it hard to know where different elements are tested.
Is there any chance of resurrecting this? What else needs doing for it to be mergeable? |
Do you want to put together another PR? We now have a postgres only mixin, so we could do the same style for mysql and postgres to get past the database specific concat syntax. Which I think was the only issue. I did find an old gem called |
@iainbeeston sorry for the delay here. Yes, this is still on my radar. |
Hi,
Here's a pure-SQL support for getting all the leaves of the tree. Basically making sure that for every record there's other record that references it's ancestry. I had to use OR in the JOIN because ancestry might be nil.