Rails 実装 検索して表示 小ネタ

f:id:happy_teeth_ago:20180715013614p:plain:w300

  <%= link_to :of_today_plan_items, class: 'list-group-item' do %>
    <i class='fa fa-list'></i> 今日の予定表
  <% end %>

なぜ do で回すのか?
link_to定義は

link_to ( HTMLで表示する文字列 , url(routes)に記載しているもの,[option])

というふうに記載する

classはcssの設定をオプションで指定。
この書き方のメリットはアイコンと表示文字を次の行にて記載できる点である。

Font Awesomeのアイコンを埋め込む場合はブロックのほうがいい。

コードが、簡潔でわかりやすい。

Urlヘルパーはroutesで resources を利用しているので自動的に生成される。

resources :plan_items do
    get :of_today, on: :collection
  end

ちなみにここではネストしている。 plan_itemsの配下に of_todayがネストされている。
アドレスを見るとわかりやすい。
結局ルーティングはアドレス。

f:id:happy_teeth_ago:20180715013004p:plain:w300

plan_itemsは基本7つのメソッドを持つ その配下にof_todayがあるということ。
このof_todayも7つのメソッド、

index,show,new,create,edit,update,destroy

を持っている。
これがルーティングの基本なのでここはしっかりと抑えること。

次に画面について、これが

f:id:happy_teeth_ago:20180715014652p:plain:w300

このように切り替わるのは、なぜだろう?さあ考えてみよう!

f:id:happy_teeth_ago:20180715014728p:plain:w300

まず、予定表と今日の予定表のボタンがある。 これはボタンだと推定される。
その下には、toDoリストがあるが、今日の予定を押すと その日のToDoに絞られて表示される。 これはおそらくコントローラでその日のToDoを取得する関数を書いているはず。 そして、その変数をブロックで回して、その下に表示しているに違いない。 まずは、viewから見ていきたい。 まず予定表のボタン

<%= render 'index_nav' %>

これはパーシャル部分テンプレートを呼び出している。その部分は

<ul class='nav nav-pills my-2'>
  <% %i(index of_today).each do |action| %>
    <li class='nav-item'>
      <%= plan_items_nav_link(action) %>
    </li>
  <% end %>
</ul>

%i は要素がシンボルの配列を生成する。

index と of_todayが入って来るので、2回ループする。

index: '予定表',
of_today: '今日の予定表'

これはヘルパーで宣言されている。

ACTION_LABEL_MAPはハッシュ、swiftで言うところの列挙体の様なイメージ。

文字列がどれに対応しているか示す。

  ACTION_LABEL_MAP = {
    index: '予定表',
    of_today: '今日の予定表'
  }

どうしてこれが表示されるのかと言うと、ヘルパーに書いてある関数を見ればわかる。

<%= plan_items_nav_link(action) %>
  def plan_items_nav_link(action)
    label = ACTION_LABEL_MAP[action]
    url = (action == :index ? :plan_items : [ action, :plan_items ])
    html_classes = %w(nav-link)
    html_classes << 'active' if action.to_s == params[:action]
    link_to label, url, class: html_classes.join(' ')
  end

つまりactionには、予定表、今日の予定表がブロックで入ってくる

かっこいい!

 # GET (collection)
  def of_today
    t0 = Time.current.beginning_of_day
    t1 = t0.advance(hours: 24)
    @plan_items = PlanItem
      .where('starts_at >= ? AND starts_at < ?', t0, t1)
      .or(PlanItem.where('ends_at > ? AND ends_at <= ?', t0, t1))
      .natural_order
    @continued_plan_items = PlanItem
      .where('starts_at < ? AND ends_at > ?', t0, t1)
      .natural_order
    render action: :index
  end

render action

このオプションは、他のアクションのテンプレートを表示する。 .advance(hours: 24)は日付関連のrailsのメソッドここでは24時間後を取得。 求めたい日付の、最初の時刻と最後の時刻を取得する。 その後where句にて絞り込みをする。1日の範囲を指定。

where句とは、SQL文

検索や、更新するときのいちばん大切な句 結果が必ず真か偽となる条件を記載しないといけません。 例文

DELETE FROM テスト WHERE 得点 < 20
テストテーブルから、得点が20点以下のものを削除する という意味 

**もう一度plan_items_nav_linkを振り返る。

  def plan_items_nav_link(action)
    label = ACTION_LABEL_MAP[action]
    url = (action == :index ? :plan_items : [ action, :plan_items ])
    link_to label, url, class: html_classes.join(' ')
  end

ちなみに、この記事で参考にしているソースは、

Ruby on Rails 5 初級④ です
MITライセンスでした。
この本はRailsの勉強には、とてもいい本でした。
是非!Railsの勉強をしている方は購入してみてください。