-
-
Notifications
You must be signed in to change notification settings - Fork 807
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
CI against Rails 6-0-stable broken #1081
Comments
I'll try to look at this soon. |
Anything we can do to help mitigate or debug this issue @seanfcarroll? We have confirmed the issue remains with rails releases We have some of our more complex search queries generating invalid SQL when attempting to update to rails |
Thanks for the ping @macfanatic Sorry I haven't had time to work on it. I will be able to look at it during the Christmas week. If you are interested in making a PR with any code investigations or failing tests for this specific problem, that could be helpful. All the best 👍 |
Here is a rails bug script showing that with rails # frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "activerecord", "6.0.0", require: "active_record"
gem "ransack", "2.3.0"
gem "sqlite3"
end
require "minitest/autorun"
require "logger"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :organizations, force: true do |t|
t.string :name, null: false
t.string :type, null: false
t.timestamps
end
create_table :products, force: true do |t|
t.string :name, null: false
t.references :seller, foreign_key: { to_table: :organizations }, null: false
t.references :manufacturer, foreign_key: { to_table: :organizations }, null: false
t.timestamps
end
end
class Organization < ActiveRecord::Base
validates :name, presence: true
end
class Seller < Organization
has_many :products
end
class Manufacturer < Organization
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :seller
belongs_to :manufacturer
validates :name, presence: true
end
class BugTest < Minitest::Test
def test_generated_sql_join
manufacturer = Manufacturer.create!(name: 'ABC Toys, LLC')
seller = Seller.create!(name: 'Amazon, Inc')
product = Product.create!(name: 'Toy Ball', manufacturer: manufacturer, seller: seller)
term = 'Toy'
query = Product.includes(:manufacturer, :seller).ransack(name_or_seller_name_or_manufacturer_name_cont: term)
assert_equal query.result.count, 1
end
end |
Hi @seanfcarroll is there anything specific I could look at to help get this resolved? I'm new to the project so diving in and making a meaningful fix will be difficult, but I have multiple projects locked to rails |
Hi @macfanatic I don't have time to work on this, however I am looking for a developer to do it. There is some budget from open collective sponsorship to pay for it. If Ransack is useful to you, please consider contributing some small amounts and then noting which issues you would like fixed. |
I tried to look into this today - hopefully I will get to continue. I'm only my findings here as other developers more experienced on Ransack might be able to point me in the right direction. It seems that by the time you get to
_join to the aliases for join dependencies) and then the conditions generated by viz.accept(search.base) would still work.
To my thinking as eventually both should be resolved by Arel Nodes the table alias names should be the same, but they're obviously not. I'm only so far as to be able to say that it appears that the result from The below are partial queries In our App Rails 6.0.0 looks like
In Rails 6.0.2 we get
|
One place to look is the Rails 6 release notes. These in particular look like they could be a possible cause: Ransack also has code added for Rails 6, inside Polyamorous. I read this code mean that the Rails 6 Polyamorous code is specific to minor versions, so ar_version = ::ActiveRecord::VERSION::STRING[0,3]
%w(join_association join_dependency reflection).each do |file|
require "polyamorous/activerecord_#{ar_version}_ruby_2/#{file}"
end irb(main):003:0> ::ActiveRecord::VERSION::STRING
=> "5.2.3"
irb(main):004:0> ::ActiveRecord::VERSION::STRING[0,3]
=> "5.2" Looking in the 6.0.1 release notes, there are quite a lot of changes for AM/AR
One final thing, when Polyamorous was absorbed into Ransack, the tests we left behind. These definitely need to be brought over and expanded for any 6.0 changes. CC @mohdsameer |
Not sure if you noticed, but I did bisect this, and included the specific change in Rails that caused this in the issue description. |
Thanks @deivid-rodriguez do you mean rails/rails@dd46d18 ? |
Yes. |
@seanfcarroll @deivid-rodriguez FYI I have approval from my work to spend time about 3 days worth of my time over the next couple of weeks on this issue and just getting a better idea about how Ransack works in general. I'll quite likely get back to working on this issue tomorrow. This will be our first trial at this type of thing for our team, but I hope we'll actually be dedicating more of our team's time to Ransack and other gems we use in 2020. Items like you discussed about Polyamorous and also I think some good developer documentation would be the types of plumbing and grunt work we'd like to help out with. |
@ozzyaaron wow that is completely awesome! Thank you to you and your employer! I'm perfectly happy for you to work on any issue you want. Good developer documentation on Ransack internals would be really great as we need to find a way to lower to bar for the community to contribute. Please ping me at any time if you need help or direction. Welcome! P.S. I've got some big ideas for the future of Ransack, and will put them on the table for community discussion. But first I think we need to get it stabilized and close out all the old issues (either fix or close). |
Confirming removal of rails/rails@dd46d18#diff-bf6dd6226db3aab589916f09236881c7R1111-R1114 fixes my own test case anyway. @seanfcarroll I'm just putting breakpoints at locations I think might be promising, I tried using something smarter like So far it seems that loosely there are two sides to building the query, building the necessary joins and then building the conditions and putting them together via a If I call The issue I'm trying to figure out is how does At this stage, if you have time, are you able to give a quick run down on how |
@ozzyaaron did you manage to find a solution or know what needs to be done to fix this issue? We too are affected by this issue and are investigating a solution. Maybe we could share our resources to come up with a solution together? |
@malachewhiz TLDR; I am making slow progress on this over my weekends but have no idea when I would understand enough Ransack, ActiveRecord and AREL to properly fix the issue. I know what Rails change caused the issue (detailed above by initial post) and I know where in Ransack the issue is coming from (I kind of outlined above) but I don't know how to fix it yet and I certainly don't understand any of the code or its intentions enough to feel confident in any fix I would make. As of last weekend I can say that for some reason when the AST (I guess) or AREL objects is built up for some reason there seems to be a difference between the object shared between what builds the joins or data collection part of the query and what builds the conditions/clauses part of the query. I'm still trying to track down why but there is a little piece of code that is given arguments one of which is I have been spending a few hours over the last couple of weekends in my own time just trying to document what actually happens when you call It has given me a lot of respect for people that work in these areas. I'm sure once you get familiar it becomes easier, like with any domain, but I really was hoping to just jump in and fix it pretty quickly. That has not happened :P |
@ozzyaaron thanks for your in-depth reply! We came to the same conclusion, that it would need a lot of effort to understand the inner-workings of all the gems in play here to make up a general fix. We ultimately patched it by adding this in an initializer (rails 6.0.2.1, ransack 2.3.2): module Polyamorous
module JoinDependencyPatch
def base_klass; end
end
end
Polyamorous::JoinDependency.prepend(Polyamorous::JoinDependencyPatch) I don't know if that's the recommended approach, but it seems to work for us. Maybe it will help someone else with this issue (or to come up with a better solution). |
@malachewhiz as stated, I'm no pro here but I would probably steer clear of that type of patch as it is may have other unintended circumstances. Obviously up to you based on your own automated tests and whatnot. Internally Just to confirm (for me, too)
My understanding is that you have haven't exactly removed My understanding of the code so far is that if this were the patch to be made, we could patch the gem with a new version of I decided to try your patch anyway and just as an FYI it doesn't fix the issue I am having with Rails 6.0.2.1 and Ransack 2.3.2. Just as some further test data, if you don't mind, are you able to post an example of the relevant model structure and params to the |
@seanfcarroll @deivid-rodriguez the more I have read the code the more I think that the change introduced into Rails that caused this issue in Ransack probably has unintended side-effects like we're seeing. It changes the collection part of the query by adding I have a patch for Ransack that duplicates the popped
I think being told why this approach is wrong might help me out in figuring out how to really fix it. Are there any good resources to look into wrt Arel & ActiveRecord? I personally couldn't find anything past the very basics and quite a few of the ActiveRecord PRs seem really hastily written and merged like the one I @deivid-rodriguez referenced. I'm still trying to find out how the attributes in Thanks again for any help! EDIT: the above patch fixed some issues but not all. I still think the root fix will be to find a way for the attribute to find its proper table alias. I changed to this. By swapping the joins the offending code never runs in Rails own
|
@ozzyaaron I'm sorry I currently have no time to dig into this, and I'm not even sure I would even succeed or make any progress. But I want to THANK YOU so much for putting so much effort into fixing this. I really appreciate it 💜. |
TLDR, see below for a fix that works for us an I think is a little bit understandable (hopefully). 🤞 I'm not going to claim this is the nicest fix but I think it actually gets to the heart of the issue (more below). I think in general there needs to be a better connection between As part of this work I actually found that the Rails commit created a JOIN order issue for us regardless of the use of Ransack. I think there are two issues here:
The 'fix' below works for us, and I think works for me conceptually as far as my understanding of the tree structure that Arel uses for a JOIN. I've tried to comment in the code rather than go into further explanation here. As I've said numerous times, I am not a pro in any of these areas. I'd actually love to get some time with anybody that has deep ActiveRecord & Arel knowledge as I think there must be a better way to say use the actual JoinDependency object and do a search of the Arel AST later. I would think that there is a way for Attribute to later find the objects in the tree rather than setup a static reference when Attribute is created. That being said I think you'd still need to have a reference in Attribute for that anyway such as the JoinDependency or the association's reflection chain. The code below passes the Ransack tests bar one that I'm not even sure is a valid failure. I think the failure is due to the JOIN order change introduced by the commit to Rails at question as I believe it re-orders how JOIN and default scope are applied. I also added some tests of my own and additions to the schema so that I could first reproduce the issue. It passed all of our Application's tests which are fairly extensive (~20k specs, ~1400 scenarios). Just to be clear the below is part of an initializer in our App currently and passes all of our automated tests. I'd like to perhaps get feedback on this before I go about creating a PR for Ransack.
|
FWIW I tried this against our production code and found that |
@varyonic same here now with Rails 6.0.3 wrt your finding about The patch that closed this issue doesn't seem to fix the original issue @seanfcarroll. We can still reproduce the original error I gave above using Ransack master. |
Agreed. As I commented in #1113 (comment), I believe the patch only adapted specs to expect the wrong thing, but didn't seem to fix the issue. |
@deivid-rodriguez indeed. I've added two test examples here #1119 (comment) - one passing and one failing that prove your point and address the error. |
CI is broken against 6-0-stable since rails/rails@dd46d18.
Needs to be investigated and fixed.
The text was updated successfully, but these errors were encountered: