###前提・実現したいこと
airbnbのような物件の予約サイトを作成しており、物件をの検索機能を実装中です。予約したい日にち(チェックイン〜チェックアウト)で検索した際、すでにその日にちで予約が入っている物件を検索結果から除外するコードを書いています。
###発生している問題
以下のようなコードを書いたのですが、予約が入っているのに表示されたり、予約が入っていないのに表示されなかったりします。エラーメッセージはありません。その現象に規則性があるかどうか、現時点では突き止められていません。ただし、検索するチェックイン日とチェックアウト日の組み合わせが同一の場合は、問題があるかないかにかかわらず、必ず同一の検索結果隣ます。
binding.pryで検証したところ、コードの最後のセクションにあるeachメソッドに処理漏れが発生しているようです。DB上にはlistingが5件あり、@listingsにはそのすべてがちゃんと入っていることは確認済みです。ところが、5件に対して3件のみにeachの処理をしている(時にlisting_idの1,3,5のみ、時に1,2,4のみ、時に5件全て処理している、など)、というような謎の現象が発生しており、これ以上の究明はお手上げ状態です。何卒お力添えをお願いいたします。
###該当のソースコード
controllerです。なお、日付以外の条件でソートするransackも機能していませんが、先に上記の問題を解決したく、ransackについては未追究です。
def search if params[:search].present? session[:address] = params[:search] if params["lat"].present? & params["lng"].present? @latitude = params["lat"] @longitude = params["lng"] geolocation = [@latitude,@longitude] else geolocation = Geocoder.coordinates(params[:search]) @latitude = geolocation[0] @longitude = geolocation[1] end @listings = Listing.where(active: true).near(geolocation, 20, order: 'distance') # 検索欄が空欄の場合 else @listings = Listing.where(active: true).all @latitude = @listings.to_a[0].latitude @longitude = @listings.to_a[0].longitude end # Ransack q のチェックボックス一覧 if params[:q].present? if params[:q][:price_pernight_gteq].present? session[:price_pernight_gteq] = params[:q][:price_pernight_gteq] else session[:price_pernight_gteq] = nil end if params[:q][:price_pernight_lteq].present? session[:price_pernight_lteq] = params[:q][:price_pernight_lteq] else session[:price_pernight_lteq] = nil end if params[:q][:home_type_eq_any].present? session[:home_type_eq_any] = params[:q][:home_type_eq_any] session[:House] = session[:home_type_eq_any].include?("House") session[:Apartment] = session[:home_type_eq_any].include?("Apartment") session[:Studio] = session[:home_type_eq_any].include?("Studio") else session[:home_type_eq_any] = "" session[:House] = false session[:Apartment] = false session[:Studio] = false end if params[:q][:pet_type_eq].present? session[:pet_type_eq] = params[:q][:pet_type_eq] else session[:pet_type_eq] = nil end if params[:q][:breeding_years_gteq].present? session[:breeding_years_gteq] = params[:q][:breeding_years_gteq] else session[:breeding_years_gteq] = nil end end # Q条件をまとめたものをセッションQに入れる session[:q] = {"price_pernight_gteq"=>session[:price_pernight_gteq], "price_pernight_lteq"=>session[:price_pernight_lteq], "home_type_eq_any"=>session[:home_type_eq_any], "pet_type_eq"=>session[:pet_type_eq], "breeding_years_gteq"=>session[:breeding_years_gteq]} # ransack検索 @search = @listings.ransack(session[:q]) @result = @search.result(distinct: true) #リスティングデータを配列にしてまとめる @arrlistings = @listings.to_a # start_date end_dateの間に予約がないことを確認.あれば削除 if ( !params[:start_date].blank? && !params[:end_date].blank? ) session[:start_date] = params[:start_date] session[:end_date] = params[:end_date] start_date = DateTime.parse(session[:start_date]) end_date = DateTime.parse(session[:end_date]) @listings.each do |listing| # check the listing is availble between start_date to end_date unavailable = listing.reservations.where("(start_date < ? AND ? < end_date) OR (start_date < ? AND ? < end_date) OR (? < start_date AND end_date < ?)", start_date, start_date, end_date, end_date, start_date, end_date).limit(1) binding.pry # delete unavailable room from @listings if unavailable.length > 0 @arrlistings.delete(listing) end end end end
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/08/13 04:03