Skip to content
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 newer Rails versions #5

Closed
mkllnk opened this issue Jun 5, 2020 · 2 comments
Closed

Support newer Rails versions #5

mkllnk opened this issue Jun 5, 2020 · 2 comments

Comments

@mkllnk
Copy link

mkllnk commented Jun 5, 2020

Hi!

I'm in the process of upgrading an old Rails application from Rails 3.2. It depends on arboreal which doesn't support newer versions at the moment. I've seen #4 which contains a lot of good work to upgrade but needs splitting up.

I have three options:

Switching to that Arboreal fork would involve renaming a database column and incorporating changes that may not be well tested. If I have to change the database, I may as well switch to Ancestry. So really, I'm weighing up between switching to Ancestry and fixing up Arboreal's Rails compatibility myself.

What is your vision for this gem? Would you like to release new versions that are not compatible with old Ruby and old Rails? Do you see advantages of Arboreal over Ancestry? @mdub

@mdub
Copy link
Owner

mdub commented Jun 5, 2020

Hi @mklink.

To be honest, I can't commit to being a good maintainer for Arboreal, as I haven't used it myself for for almost a decade, and seldom work with ActiveRecord these days.

I think the most sensible course of action is a switch to Ancestry, which appears to be actively maintained.

Alternatively, you could work with the mavenlink folks to get Arboreal into a better state - up-to-date and well-tested. If a group emerges that wishes to actively maintain Arboreal, I'd be happy to hand over the keys.

@mkllnk
Copy link
Author

mkllnk commented Jul 28, 2020

Thank you for the heads up, @mdub. I decided to move to Ancestry. It was relatively easy. The most difficult parts were custom scopes based on matching ancestry_string. Let me share the general steps here.

Replacing Arboreal with Ancestry

-  acts_arboreal
+  has_ancestry

The main difference is that Arboreal uses the ancestry_string column and Ancestry uses ancestry. The delimiter is / instead of - and Ancestry doesn't use delimiters add the beginning and end. Check Ancestry for a migration to add the new column. Then I used this migration for the data:

  def up
    execute "UPDATE product_types SET ancestry = REPLACE(TRIM('-' FROM ancestry_string), '-', '/') WHERE ancestry_string LIKE '-%-'"
  end

Delimiter caveat

Ancestry doesn't use enclosing delimiters. This can trip you up if you use queries matching a part of ancestry_string to find a subtree. If you search without delimiter at the end, you can accidentally find other rows not belonging to the subtree and if you add the delimiter at the end you find only children.

NULL caveat

The ancestry value is NULL for root nodes. So it's easy to accidentally ignore all root nodes in a query because SQL treats every expression comparing with NULL as false. Here's an example to deal with that:

  scope :ordered_by_child_ancestry, -> {
-   order("CONCAT(ancestry_string, id, '-')")
+   order("IFNULL(CONCAT(ancestry, '/', id), id)")
  }

Obsolete usages

Make sure you find all places that use methods or columns that don't exist any more. parent_id is now a method provided by Ancestry and if you use the column in your SQL queries, you have to replace that. The method path_string is gone. I mainly replaced it by using subtree_ids.

Rails 3 caveat

Ancestry still supports Rails 3 but I found one incompatibility: it uses the none scope introduced in Rails 4. So I patched my model using ancestry:

  # Forward compatibility with Rails 4 which is needed by ancestry.
  scope :none, -> {
    where("false")
  }

@mdub mdub closed this as completed Jul 28, 2020
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

No branches or pull requests

2 participants