Вы пробовали толкая каждый из or
запросов на отдельные именованные в Post
модели ? Для меня расщепление их привело к различным результатам. Попробуйте что-то вроде кода ниже и посмотреть, если вы получите ожидаемый результат (я не имею Rails приложение под руку, чтобы я положил все в один файл Ruby):
rails_where_or.rb
require 'active_record'
require 'rspec'
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3', database: ':memory:'
)
ActiveRecord::Schema.define do
create_table :posts do |t|
t.boolean :a, default: false
t.boolean :b, default: false
t.boolean :c, default: false
t.boolean :d, default: false
end
end
class Post < ActiveRecord::Base
def self.a_or_b_and_c_or_d
a_or_b.c_or_d
end
def self.a_or_b_and_c_or_d_all_chained
where(a: true).or(where(b: true)).
where(c: true).or(where(d: true))
end
def self.a_or_b
where(a: true).or(where(b: true))
end
def self.c_or_d
where(c: true).or(where(d: true))
end
end
RSpec.describe Post do
let!(:only_a) do
described_class.create!(a: true)
end
let!(:only_b) do
described_class.create!(b: true)
end
let!(:only_c) do
described_class.create!(c: true)
end
let!(:only_d) do
described_class.create!(d: true)
end
let!(:a_and_b) do
described_class.create!(a: true, b: true)
end
let!(:a_and_c) do
described_class.create!(a: true, c: true)
end
let!(:a_and_d) do
described_class.create!(a: true, d: true)
end
let!(:b_and_c) do
described_class.create!(b: true, c: true)
end
let!(:b_and_d) do
described_class.create!(b: true, d: true)
end
let!(:c_and_d) do
described_class.create!(c: true, d: true)
end
describe '.a_or_b_and_c_or_d' do
let(:a_or_b_and_c_or_d) do
described_class.a_or_b_and_c_or_d
end
it 'returns only records that match (A || B) && (C || D)' do
expect(a_or_b_and_c_or_d).not_to include(only_a)
expect(a_or_b_and_c_or_d).not_to include(only_b)
expect(a_or_b_and_c_or_d).not_to include(only_c)
expect(a_or_b_and_c_or_d).not_to include(only_d)
expect(a_or_b_and_c_or_d).not_to include(a_and_b)
expect(a_or_b_and_c_or_d).not_to include(c_and_d)
expect(a_or_b_and_c_or_d).to include(a_and_c)
expect(a_or_b_and_c_or_d).to include(a_and_d)
expect(a_or_b_and_c_or_d).to include(b_and_c)
expect(a_or_b_and_c_or_d).to include(b_and_d)
end
end
describe '.a_or_b_and_c_or_d_all_chained' do
let(:a_or_b_and_c_or_d_all_chained) do
described_class.a_or_b_and_c_or_d_all_chained
end
it 'returns records that match (A || B) && C || D ' do
expect(a_or_b_and_c_or_d_all_chained).not_to include(only_a)
expect(a_or_b_and_c_or_d_all_chained).not_to include(only_b)
expect(a_or_b_and_c_or_d_all_chained).not_to include(only_c)
expect(a_or_b_and_c_or_d_all_chained).not_to include(a_and_b)
expect(a_or_b_and_c_or_d_all_chained).to include(only_d)
expect(a_or_b_and_c_or_d_all_chained).to include(c_and_d)
expect(a_or_b_and_c_or_d_all_chained).to include(a_and_c)
expect(a_or_b_and_c_or_d_all_chained).to include(a_and_d)
expect(a_or_b_and_c_or_d_all_chained).to include(b_and_c)
expect(a_or_b_and_c_or_d_all_chained).to include(b_and_d)
end
end
end
Вы нашли решение, которое вы хотели? –