先週末から検索機能のフォームデータのやりとりでハマってた。
思わぬ落とし穴って感じ。いい勉強になりました。

今日のやったこと、できたこと

  • クラウドソーシング対応
  • パッケージデザイン
  • システムメンテナンス
  • プログラミング
  • ウェブデザイン
  • 読書

明日への課題

  • 取引先のホームページ更新
  • プログラミング

今日のワーク

今回ハマったのは、フォームからデータを送信する時。
フォームの項目が日時の時に、Railsの機能で「datetime_select」や「date_select」という機能を使うことができる。

このフォームは、自動で年月日時分を選択できるフォームを生成してくれる。
ただこのフォームはちょっと変わってて元の項目が :hogehoge なら :hogehoge(1i) 〜 :hogehoge(5i)の間で生成される。

ただ、この項目で送られたデータはRailsのActiveRecordが勝手に元の項目に戻してくれる。
データベースの項目の型が日付系「date」や「datetime」なら何にも問題ない。

ただ、項目の型が日付系以外だと大きな問題になる。自動的に処理してくれないから。
今回は自分は「attr_accessor」で定義した項目だった。

なので、そもそも型とかないしデータベースとも関係ないので、自動的に変換もしてくれない。
といっても、今回は検索フォームだったので、フォームの値を取得できればOK。

で、プログラム的にはObject.newでしか使っていなかったので、initializeのところを編集した。
具体的にはこんな感じ。

コントローラーでは、

@search_form = SearchForm.new(strong_params)

としてフォームからのデータを受け取っているので、そのForm用のクラスに追加で

def initialize(params = {})
  if params.is_a?(ActionController::Parameters)
    [:date_start, :date_end].each do |attribute|
      date_parts = (1..3).map { |i| params.delete("#{attribute}(#{i}i)") }
      params[attribute]= Time.zone.local(*date_parts) if date_parts.any?
    end
  end
  super
end

の処理を追加した。

つまり、なにをしているかと言えば、Objectのnewした時に呼び出されるメソッド「initialize」に渡される引数paramsがフォームから受け取ったデータのこと。

で、本来の項目名分データを読み取りdate_selectが生成した項目を削除し、削除した項目を元に日付データを作成して、新しい項目として本来の項目名のデータを追加する。

つまり、newの時に自動変換してくれる処理を追加したわけです。
これは以下のサイトを参考にさせていただきました。

https://teratail.com/questions/57198

今回はmodelにinsertしたりupdateしたりとかはなかったのでnewだけで済んだのは助かったかな。
意外にあっさり解決できたといっても、3時間くらい調べてたけど。

ほんと、知らないことだらけで教えてくれる人もいないから一回ハマるとめっちゃ時間かかる。
こんなことばっかりですよ。でも嫌いじゃないんだけど。

やっとこさ、システムのプログラム自体は大体終わってて、あとはデザインを残すのみって感じ。
なので今日は、dwawer導入したりFont Awesomeなどのwebフォントを導入したり、CSS書いたりHTMLなおしたりって感じであっという間の4時間でした。

コーディングやデザインって難易度は高くないけどそれなりに時間取られるんだよね。
ここをもっと効率化できたらいいかなって思ってhaml導入したけど、限界あるなぁ。

そんなわけで、もう少しで大体完成するんじゃないかなって思う。
公開できるのが楽しみだな。って、AWSでドメイン設定したりも未経験なので壁はまだまだありますけどね。

そんな感じ。