Rails中如何实现按用户名及预订创建日期范围搜索?
实现按用户名和预订日期范围搜索预订用户
问题背景
现有Booking、Property、User模型关联如下,需要添加搜索功能,支持按用户名和预订创建的日期范围筛选展示的预订用户:
class Booking < ApplicationRecord belongs_to :user belongs_to :property has_many :inquiries, dependent: :destroy enum status: [:Pending, :Approved] end class Property < ApplicationRecord belongs_to :user has_many :bookings, dependent: :destroy belongs_to :comapny has_many :reviews , dependent: :destroy end class User < ActiveRecord::Base has_many :properties has_many :bookings has_many :inquiries has_one :comapny has_many :reviews end
实现步骤
1. 在Booking模型中添加搜索作用域
通过作用域封装查询逻辑,关联User表实现用户名匹配,同时处理日期范围筛选:
class Booking < ApplicationRecord # 原有代码保持不变 belongs_to :user belongs_to :property has_many :inquiries, dependent: :destroy enum status: [:Pending, :Approved] # 添加搜索作用域 scope :search_by_user_and_date, ->(username, start_date, end_date) do bookings = joins(:user) # 用户名模糊匹配 bookings = bookings.where("users.name LIKE ?", "%#{username}%") if username.present? # 按预订创建日期筛选,若需按预订起止日期,替换为对应字段即可 if start_date.present? && end_date.present? bookings = bookings.where(created_at: start_date.to_date.beginning_of_day..end_date.to_date.end_of_day) elsif start_date.present? bookings = bookings.where("created_at >= ?", start_date.to_date.beginning_of_day) elsif end_date.present? bookings = bookings.where("created_at <= ?", end_date.to_date.end_of_day) end bookings end end
2. 在控制器中处理搜索参数
假设在BookingsController的index方法展示预订用户,添加参数处理逻辑:
class BookingsController < ApplicationController def index # 获取页面提交的搜索参数 @username = params[:username] @start_date = params[:start_date] @end_date = params[:end_date] # 调用作用域筛选预订 filtered_bookings = Booking.search_by_user_and_date(@username, @start_date, @end_date) # 提取唯一的预订用户,避免同一用户多条预订重复显示 @users = filtered_bookings.map(&:user).uniq end end
3. 在视图中添加搜索表单
在预订用户列表页面顶部添加搜索表单,让用户输入查询条件:
<%= form_tag bookings_path, method: :get do %> <div class="search-group"> <%= label_tag :username, "用户名" %> <%= text_field_tag :username, @username, placeholder: "输入用户名搜索" %> </div> <div class="search-group"> <%= label_tag :start_date, "开始日期" %> <%= date_field_tag :start_date, @start_date %> </div> <div class="search-group"> <%= label_tag :end_date, "结束日期" %> <%= date_field_tag :end_date, @end_date %> </div> <%= submit_tag "搜索", class: "search-btn" %> <% end %> <!-- 展示筛选后的用户列表 --> <h3>预订用户列表</h3> <ul> <% @users.each do |user| %> <li><%= user.name %> - 累计预订:<%= user.bookings.count %>次</li> <% end %> </ul>
注意事项
- 如果用户表存储用户名的字段不是
name,需将users.name替换为实际字段(如users.username)。 - 若要按预订的入住/退房日期筛选,把
created_at替换为对应的业务字段(如check_in_date)。 - 可额外添加前端验证,比如限制结束日期不能早于开始日期,提升用户体验。
内容的提问来源于stack exchange,提问作者muq03
相关产品推荐
相关产品推荐

