activerecord-hackery / ransack

Object-based searching.
https://activerecord-hackery.github.io/ransack/
MIT License
5.65k stars 795 forks source link

Behavior when 'and' and 'or' are mixed in the symbol representing the target column #1019

Open akicho8 opened 5 years ago

akicho8 commented 5 years ago

Steps to reproduce

require "active_record"
require "ransack"
require "ransack/version"

ActiveRecord::VERSION::STRING           # => "5.2.3"
Ransack::VERSION                        # => "2.1.1"

ActiveRecord::Migration.verbose = false
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Schema.define do
  create_table :users do |t|
    t.integer :x
    t.integer :y
    t.integer :z
  end
end

class User < ActiveRecord::Base
end

def _(*v)
  sql = User.ransack(*v).result.to_sql
  sql = sql.remove('"')
  sql = sql.remove("SELECT users.* FROM users WHERE ")
  sql = sql.remove("users.")
end

_ x_and_y_eq: 0       # => "x = 0 AND y = 0"
_ x_or_y_eq: 0        # => "(x = 0 OR y = 0)"

_ x_and_y_and_z_eq: 0 # => "x = 0 AND y = 0 AND z = 0"
_ x_or_y_or_z_eq: 0   # => "((x = 0 OR y = 0) OR z = 0)"

_ x_or_y_and_z_eq: 0  # => "((x = 0 OR y = 0) OR z = 0)"
_ x_and_y_or_z_eq: 0  # => "x = 0 AND y = 0 AND z = 0"

Expected behavior

Last two lines.

_ x_or_y_and_z_eq: 0  # => "(x = 0 OR (y = 0 AND z = 0))"
_ x_and_y_or_z_eq: 0  # => "((x = 0 AND y = 0) OR z = 0)"

I don't know if it's a bug or a specification, but I think it would be kind to the user if there was a warning etc if the SQL was different from the intention against the written syntax.

Actual behavior

_ x_or_y_and_z_eq: 0  # => "((x = 0 OR y = 0) OR z = 0)"
_ x_and_y_or_z_eq: 0  # => "x = 0 AND y = 0 AND z = 0"
scarroll32 commented 3 years ago

This code is kind of blowing my mind ...