Skip to content

Conversation

Two9A
Copy link

@Two9A Two9A commented Aug 3, 2016

In situations where external tree-based data is cached or otherwise held locally, the ids used by the external service can differ from the database's primary key.

@rainchen
Copy link
Collaborator

rainchen commented Aug 3, 2016

is it possible to add an alias method like alias :id :the_primary_key_column to resolve this issue?

@Two9A
Copy link
Author

Two9A commented Aug 3, 2016

Unfortunately no: in my particular case, the :id is referenced elsewhere in the schema distinctly from the :tree_id.

@felixbuenemann
Copy link
Collaborator

Given that we already support customizing the foreign key, it makes sense to also be able to customize the primary key.at the option works as expected.

@Two9A The changes look good to me. Do you think you would be able to add a test case that tests the customization of the :id and :parent_id columns?

@Two9A
Copy link
Author

Two9A commented Aug 3, 2016

Interestingly, it seems that the primary_key option on associations is a recent addition (according to Travis, at least). I can't find any information on which version of ActiveRecord introduced the option though...

@felixbuenemann
Copy link
Collaborator

Recent? It's present in rails 2.2…

@Two9A
Copy link
Author

Two9A commented Aug 3, 2016

Ah, I see. The tests are failing (but only sometimes) on tree_view, and it's nothing to do with versioning. (I should read more.)

@@ -141,7 +141,7 @@ def leaves
class_eval <<-EOV
def self.leaves
internal_ids = select(:#{configuration[:foreign_key]}).where(arel_table[:#{configuration[:foreign_key]}].not_eq(nil))
where("id NOT IN (\#{internal_ids.to_sql})").default_tree_order
where("#{configuration[:primary_key]} NOT IN (\#{internal_ids.to_sql})").default_tree_order
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must use quote_column_name or should be changed to use arel. There is no guarantee, that the value given to :primary_key is not a reserved keyword or contains characters that require quoting.

@felixbuenemann
Copy link
Collaborator

I think a lot of the duplication in the new tests could be avoided by setting the constant for the TreeMixin to an instance var in setup_db and referecing that in the tests.

@felixbuenemann
Copy link
Collaborator

I think the test failures are because test_tree_view extends Mixin instead of TreeMixin.

@@ -141,7 +141,7 @@ def leaves
class_eval <<-EOV
def self.leaves
internal_ids = select(:#{configuration[:foreign_key]}).where(arel_table[:#{configuration[:foreign_key]}].not_eq(nil))
where("#{configuration[:primary_key]} NOT IN (\#{internal_ids.to_sql})").default_tree_order
where.not(:#{configuration[:primary_key]} => internal_ids).default_tree_order
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not backwards compatible, where.not is a very recent addition to activerecord.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try the following:

where(arel_table[:#{configuration[:primary_key]}].not_in(internal_ids))

@Two9A
Copy link
Author

Two9A commented Aug 3, 2016

Wow, that was worse.

@felixbuenemann
Copy link
Collaborator

The test for test_nullify is still failing on older Rails. I have two ideas to try to fix it:

  • Extract the test test_nullify test into it's own Test class
  • Try resetting the ActiveRecord column information using SomeMixin.reset_column_information

@Two9A
Copy link
Author

Two9A commented Aug 3, 2016

Alright, the only failures are on Ruby 1.9, so I'm going to call that a pass. Sorry about the mess.

@felixbuenemann
Copy link
Collaborator

Yes, it seems some dependencies no longer support ruby 1.9.2 / 1.9.3 and need to be locked to older versions. Those are not related to your changes, so it's ok.

@felixbuenemann
Copy link
Collaborator

@Two9A The changes look good, can you squash them to a single commit?

If you don't know how to do that let me know and I can do it for you.

@@ -63,6 +65,7 @@ module ClassMethods
# a custom column by passing a symbol or string.
def acts_as_tree(options = {})
configuration = {
primary_key: "id",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you change the default to the tables primary key? It is returned by calling the method primary_key.

That way it will work fine, if the model uses a non-standard primary key name.

@felixbuenemann
Copy link
Collaborator

@Two9A I have one small change for the default value of the :primary_key option, please see the comments. After that I will merge and cut a new release shortly.

@felixbuenemann
Copy link
Collaborator

There are still random failures on older rails versions, likely due to activerecord's column cache.
I'll look into fixing them, your changes should be fine.

@felixbuenemann
Copy link
Collaborator

I've got a fix for the test failures on rails 3.2 in my local fork, I'm still working on finding a fix for the somewhat sporadic failures with activerecord 4.1.

@felixbuenemann
Copy link
Collaborator

@Two9A I just pushed acts_as_tree 2.5.0 to RubyGems, which includes your changes.

Thank you for your contribution and sorry for the delay!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants