Reputation: 1698
I have two tables: Transactions and Properties.
I have one condition to satisfy that doesn't require joining tables.
On my Transactions query:
sales_date
is in a certain monthsold_or_leased
is "leased"My next condition requires joining properties to transactions so that I can:
transactions.sales_date
is in a certain monthtransactions.sold_or_leased
is null ANDproperties.for_sale
is false AND properties.for_lease
is trueBasically, a new column was added to transactions called sold_or_leased
and a lot of them are null. I need to an extra query to cover the null
columns.
#test variables for month
date = "2019-11-01"
month = Date.parse date
# below satisfies my first part
@testobj = Transaction.where(sold_or_leased: "leased")
.where("sales_date >= ? AND sales_date < ?", month.beginning_of_month, month.end_of_month).count
But now I need to extend this query to include properties and test a property column
I'm not sure where to go from here:
@testobj = Transaction.joins(:property)
.where(sold_or_leased: "leased")
.where("sales_date >= ? AND sales_date < ?", month.beginning_of_month, month.end_of_month)
.or(
Transaction.where(sold_or_lease: nil)
).count
Also, when I add a join and then an or
clause, i get an error Relation passed to #or must be structurally compatible. Incompatible values: [:joins]
I will share relevant model info:
Transaction Model:
class Transaction < ApplicationRecord
belongs_to :user
belongs_to :property
end
Property Model:
class Property < ApplicationRecord
has_one :property_transaction, class_name: 'Transaction', dependent: :destroy
end
With the help of Sebastian, I have the following (which still produces the structural error message):
Transaction.joins(:property)
.where(sales_date: month.all_month,
sold_or_leased: nil,
properties: { for_sale: false, for_lease: true })
.or(
Transaction.joins(:property)
.where(sold_or_leased: "leased")
.where("sales_date >= ? AND sales_date < ?", month.beginning_of_month, month.end_of_month)
)
Upvotes: 1
Views: 540
Reputation: 33420
In theory, you should be able to access the properties
table columns after a join.
Looking to your current code and what you need to get you could try with:
Transaction
.joins(:property)
.where(sales_date: month.all_month)
.where(
"(sold_or_leased IS NULL AND properties.for_sale = false AND properties.for_lease = true) OR
(sold_or_leased = 'leased')"
)
If you're unable to use the ActiveRecord::QueryMethods#or
, you can always use the SQL OR
operator within a string argument to where
.
Notice month.all_month
produces the whole range of dates for a corresponding month, which when used with where
is converted to the first and last day of the month:
SELECT ... WHERE "transactions"."sales_date" BETWEEN $1 AND $2 AND ... [["sales_date", "2019-11-01"], ["sales_date", "2019-11-30"]]
Shorter than the month.beginning_of_month
and month.end_of_month
variation.
Upvotes: 1