我在 Rails 应用程序中编写的条件查询存在问题。目前,如果某些位置(location_north、location_south 等)为真并且某些类型(type_dining、type_unique 等)为真,我会查询商店,但我希望它查询它们,如果其中任何一个是两个,而不是全部他们是真的。
例如,如果潜在顾客将location_north和location_east设置为true,我想查询所有具有location_north或location_east的商店,商店不需要同时设置为true。
类型相同,如果潜在客户的 store_type_unique true 和 store_type_dining true,我想查询所有具有 type_unique 或 type_dining true 的商店,商店不需要两者都设置为 true。
我知道我的数据库的组织方式存在问题,但是是否可以在当前版本中进行设置?感谢您的指导,非常感谢!
def build_filters_obj
filters = []
filters.push 'location_north' if @lead.location_north
filters.push 'location_east' if @lead.location_east
filters.push 'location_south' if @lead.location_south
filters.push 'location_west' if @lead.location_west
filters.push 'location_other' if @lead.location_other
return filters
end
def perform(lead_id)
@lead = Lead.find(lead_id)
lead_email = ValidEmail2::Address.new(@lead.email)
UserNotifierMailer.send_signup_email(@lead).deliver if lead_email.valid?
@stores = Store.all
@stores = @stores.where.not(email: [nil, ''])
n = @lead.guests_total.to_i
@stores = @stores.where("capacity_min <= ? AND capacity_max >= ?", n, n)
@stores = @stores.where(:type_unique => true) if @lead.store_type_unique
@stores = @stores.where(:type_dining => true) if @lead.store_type_dining
@stores = @stores.where(:type_hotel => true) if @lead.store_type_hotel
filters = build_filters_obj
filters.each do |filter|
@stores = @stores.where(filter.to_sym => true)
end
@stores = @stores.or(Store.where(:receive_all => true))
@stores.each do |store|
store_email = ValidEmail2::Address.new(store.email)
UserNotifierMailer.send_lead_email(store, @lead).deliver if store_email.valid?
end
end
我认为这里的挑战是根据@lead的属性动态构建OR查询。这是您的执行方法的新方法:
def perform(lead_id)
@lead = Lead.find(lead_id)
lead_email = ValidEmail2::Address.new(@lead.email)
UserNotifierMailer.send_signup_email(@lead).deliver if lead_email.valid?
n = @lead.guests_total.to_i
@stores = Store.where.not(email: [nil, ''])
.where("capacity_min <= ? AND capacity_max >= ?", n, n)
# Dynamic OR conditions for types
type_conditions = []
type_conditions << Store.where(type_unique: true) if @lead.store_type_unique
type_conditions << Store.where(type_dining: true) if @lead.store_type_dining
type_conditions << Store.where(type_hotel: true) if @lead.store_type_hotel
# Dynamic OR conditions for locations
location_conditions = build_filters_obj.map { |filter| Store.where(filter.to_sym => true) }
# Combine type and location conditions
combined_conditions = type_conditions + location_conditions
# Apply OR conditions if there are any
unless combined_conditions.empty?
combined_query = combined_conditions.shift
combined_conditions.each do |condition|
combined_query = combined_query.or(condition)
end
@stores = @stores.merge(combined_query)
end
# Include stores that receive all
@stores = @stores.or(Store.where(receive_all: true))
# Send emails to stores
@stores.each do |store|
store_email = ValidEmail2::Address.new(store.email)
UserNotifierMailer.send_lead_email(store, @lead).deliver if store_email.valid?
end
end