链轨。如果有的话,在哪里选择

问题描述 投票:0回答:1

我在 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
ruby-on-rails ruby rails-api
1个回答
0
投票

我认为这里的挑战是根据@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
© www.soinside.com 2019 - 2024. All rights reserved.