Railsで曜日検索する

曜日でガラリと変わる環境なので、曜日検索がしたい。

DBに登録しているのは

  • 開始日時:dtstart(datetime型)
  • 終了日時:dtend(datetime型)

検索フォームは

  • 開始日時:@dtstart(date型)
  • 終了日時:@dtend(date型)
  • 曜日:@weekday(0が日曜日〜6が土曜日なセレクトボックス)
表示部分

app/views/iftb/search.rhtml

<%= date_select(:iftb_cond, :dtstart, {:use_month_numbers=>true}) %>
<%= date_select(:iftb_cond, :dtend, {:use_month_numbers=>true}) %>
<%= select(:iftb_cond, :weekday, [["すべて", ""]] + Iftb::WEEK) %>

app/models/iftb.cond

  WEEK = [
    ["日","0"],
    ["月","1"],
    ["火","2"],
    ["水","3"],
    ["木","4"],
    ["金","5"],
    ["土","6"]
  ].freeze
検索するパラメータをセットするところ

http://code.google.com/p/railswhere/を使っています

    #曜日検索なり
    if @weekday.blank?
      w.and("dtstart >= ?", @dtstart.to_s)
      w.and("dtend <= ?", (@dtend+ 1).to_s)
    else
      # 曜日によって差分の日付の取得方法が異なる
      if Date.today.wday > @weekday.to_i
        lastweekday = Date.today.wday - @weekday.to_i
      elsif Date.today.wday < @weekday.to_i
        lastweekday = Date.today.wday + 7 - @weekday.to_i
      else
        lastweekday = 0 # 同じ曜日
      end
      chkweekday = Date.today - lastweekday #目的の曜日の最終日を求める

      while chkweekday >= @dtstart #日付を作る
        w.or{ |sw| #登録済みのデータが日時型なので、強引な手法をとる
          sw.and "dtstart > ?", chkweekday -1
          sw.and "dtstart < ?", chkweekday +1
        }
        chkweekday = chkweekday - 7
      end
    end
    w.to_s

これで曜日の検索ができた。日付の差分を取得するところがエレガントじゃないのが気に入らない。

Railsで一つのフィールドスペースで区切られた単語をAND検索する

ながったらしい表題だなー、「Railsで曜日検索する」と同じネタ

    #複数キーワード検索
    unless @repdetail.blank?
      str = @repdetail.gsub(" "," ")
      w.and{ |sw|
      for status in str.split(" ")
        sw.and "repdetail like ?", '%' + status + '%'
      end
      }
    end

突き詰めればAND、OR、NOTも出来そうだけど面倒なり。必要になったら作る。

belong_toは陥りやすい

belong_toとhas_many、findを使うときに間違うとドツボになる。

class Schedule < ActiveRecord::Base
  belongs_to :classroom
end

class Classroom < ActiveRecord::Base
  has_many :schedules
end

こんな関係になっているときに、

@patroom_arrays = Schedule.find(:all,
:select=>"classroom_id,distinct classroom.name",
:include=>:classroom)

こんなことをやっても希望通りに行かない。

@patroom_arrays = Classroom.find(:all,
:select => "schedules.classroom_id, distinct name",
:include=>:schedules)

主(親とかって言い切りたい)からFindしてあげないとよろしい結果にならなかった。

あっちこっちで「ハマる」とかいてあったのがやっと分かった。