簡體   English   中英

搜索多個表並將結果添加到數組

[英]Search multiple tables and add results to array

作為一個練習,我得到了一個包含三個表Booking,Room和Host的項目。 這些模型如下:

class Booking < ActiveRecord::Base
  belongs_to :room
end

class Room < ActiveRecord::Base
  belongs_to :host
  has_many :bookings
end

class Host < ActiveRecord::Base
  has_many :rooms
end

數據庫模式如下所示:

ActiveRecord::Schema.define(version: 20150305133000) do

  create_table "bookings", force: true do |t|
    t.integer  "room_id",          null: false
    t.date     "start_date",       null: false
    t.date     "end_date",         null: false
    t.integer  "number_of_guests", null: false
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "hosts", force: true do |t|
    t.string   "name"
    t.string   "address"
    t.string   "picture_url"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "rooms", force: true do |t|
    t.integer  "host_id",    null: false
    t.integer  "capacity",   null: false
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

我需要實現一個搜索功能,該功能將返回所有主機,並在搜索表單指定的日期之間提供可用的房間。 要查找在所需日期可用的主機,我需要與“預訂”表進行交叉引用。

我瀏覽了紅寶石指南 ,也瀏覽了這個問題,但是我很難實現所閱讀的內容。

在Rails控制台中,我一直在嘗試各種查詢以嘗試獲取所需的結果。

如果我讓@bookings = Booking.includes(:room).all @hosts = []@hosts = []並且如果start_dateend_dateguests是他搜索返回的參數,則運行以下查詢:

@bookings.each { |b| @hosts.push(b.room.host) if (b.start_date < start_date && b.end_date > end_date && (b.room.capacity - b.number_of_guests >= guests)) }

產生一個空的@hosts 然后我嘗試了

 Booking.joins(:room).where("start_date < ? AND end_date > ? and capacity-number_of_guests >= ?", start_date, end_date, guests)

但這也返回了空的響應,因此我嘗試着一步一步地找到所需日期的所有預訂,過濾掉沒有空間的房間,然后將所有房間的主機聚集在一起剩下。 我得到了:

@bookings = Booking.where("start_date = ? AND end_date >= ?",
  Date.parse(params[:start_date]),
  Date.parse(params[:end_date])).paginate(:page => params[:page], :per_page => 10)

@bookings.reject{ |booking| (booking.room.capacity - booking.number_of_guests) == 0 }

但是,這仍在返回空房間。 我已經在這里待了一天,所以如果有人能指出正確的方向來解決這個問題,我將不勝感激!

調試嘗試

遵循denis-bu的建議,我已經更新了我的第一個查詢以使其讀取(暫時不留房間容量):

@bookings.each { |b| @hosts.push(b.room.host) if ((b.start_date > start_date &&
  b.start_date < end_date) || (b.end_date > start_date && b.end_date < end_date)) }

我已經在rails控制台中運行了它,然后當我嘗試@hosts.count它返回0這意味着該查詢未獲取任何結果。 我希望看到一系列Host記錄。

使用我的《 Where Exists》 gem和PostgreSQL:

Room.includes(:host).where_not_exists(:bookings,
 [
   "(?, ?) OVERLAPS (start_date, end_date)",
   params[:start_date],
   params[:end_date]
 ]
)

沒有寶石:

# Using PostgreSQL OVERLAPS (http://www.postgresql.org/docs/9.0/static/functions-datetime.html)

overlaps = Booking.where(where("(?, ?) OVERLAPS (start_date, end_date)", start_date, end_date))

# With MySQL or SQLite you should check for boundaries manually

overlaps = Booking.where("? < end_date", start_date).where("? > start_date", end_date)

Room.includes(:host).where("NOT EXISTS (#{
  overlaps.where("bookings.room_id = rooms.id").to_sql
})")

關於您要實現的目標的詳細信息還不夠多,但是我猜測問題與您的條件有關: start_date < ? AND end_date > ? start_date < ? AND end_date > ? -檢查查詢日期是否在預訂間隔內,而應該檢查預訂是否與查詢日期重疊: ((b.start_date > START_DATE and b.start_date < END_DATE) OR (b.end_date > START_DATE and b.end_date < END)

但是,我想這不是您應該做的所有事情。 您還應該找到沒有預訂的房間以查詢日期,然后合並這些集合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM