Rails API中.where方法链式调用问题:门店线索匹配逻辑修正求助
修正Rails API中门店筛选逻辑的问题
原代码的核心问题
- 位置筛选逻辑错误:当线索同时选中多个位置时,原代码要求门店同时满足所有选中的位置字段为
true(逻辑AND),但实际需求应为门店满足任意一个选中的位置即可(逻辑OR)。 - 门店类型筛选逻辑错误:同理,当线索选中多种门店类型时,原代码要求门店同时具备所有选中的类型,不符合“匹配任意一种类型”的需求。
- 查询效率问题:
Store.all会先加载所有门店再逐步筛选,未利用ActiveRecord的延迟查询特性,造成不必要的性能损耗。
修正后的代码
def build_location_conditions location_fields = [] location_fields << "location_north = true" if @lead.location_north location_fields << "location_east = true" if @lead.location_east location_fields << "location_south = true" if @lead.location_south location_fields << "location_west = true" if @lead.location_west location_fields << "location_other = true" if @lead.location_other location_fields.join(" OR ") end def build_store_type_conditions type_fields = [] type_fields << "type_unique = true" if @lead.store_type_unique type_fields << "type_dining = true" if @lead.store_type_dining type_fields << "type_hotel = true" if @lead.store_type_hotel type_fields.join(" OR ") 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? # 初始化基础查询:过滤有有效邮箱的门店 base_query = Store.where.not(email: [nil, '']) # 容量筛选:客人数量在门店的容量范围内 guest_count = @lead.guests_total.to_i base_query = base_query.where("capacity_min <= ? AND capacity_max >= ?", guest_count, guest_count) # 位置筛选:满足任意选中的位置 location_conditions = build_location_conditions base_query = base_query.where(location_conditions) if location_conditions.present? # 门店类型筛选:满足任意选中的类型 type_conditions = build_store_type_conditions base_query = base_query.where(type_conditions) if type_conditions.present? # 合并接收全部线索的门店:符合筛选条件 OR receive_all=true(同时过滤无效邮箱) target_stores = base_query.or(Store.where(receive_all: true).where.not(email: [nil, ''])) # 给目标门店发送线索邮件 target_stores.each do |store| store_email = ValidEmail2::Address.new(store.email) UserNotifierMailer.send_lead_email(store, @lead).deliver if store_email.valid? end end
关键修改说明
- OR逻辑实现:通过构建SQL条件字符串,用
OR连接多个位置/类型条件,确保门店满足任意一个选中的属性即可。 - 延迟查询优化:全程使用ActiveRecord查询链,直到最终遍历才执行数据库查询,避免提前加载冗余数据。
- receive_all筛选修正:给
receive_all=true的门店也加上邮箱非空过滤,避免向无效邮箱发送邮件。 - 代码结构拆分:将条件构建拆分为独立方法,提升代码可读性和维护性。
内容的提问来源于stack exchange,提问作者Terence Devine
相关产品推荐
相关产品推荐

