LoginSignup
13
12

More than 5 years have passed since last update.

食べログのようなメニューをRailsで再現する方法を考えてみた

Last updated at Posted at 2016-01-11

食べログのようなメニューをRailsで再現しようとして、どんな方法が良いのか悩みました。結論はないけれど、どんな方法で実現するのがいいのか?考えてみました

前提:したいこと

image

  • 例えば、口コミ一覧と口コミの詳細ページは
    • 現在地表示をしたい(CSSのclass名に currentとか入れたい)
    • 現在地は、リンクを外したい(食べログはリンクになってますけれど...)
    • 口コミ数が0件だったら、非リンクにしたい
  • 環境はRuby on Rails 4.2

ルーティング

Rails.application.routes.draw do
  resources :shops do
    resources :accesses
    resources :official_photos
    resources :photos
    resources :reviews
  end
end

実現方法

current_page? を使う

current_page? を使うと、controller名や、cotroller + action名など細かい指定で、アクセスしているページ(current page)が想定通りか判別してくれます。

課題

課題なのは、/shops/:shop_id/photos/:photo_id のようなURLの指定が難しいこと。というか、諦めた。

ソース

%ul.menu
  %li
    .menu_item
      - unless current_page?(shop_path(@shop))
        = link_to '店舗', @shop
      - else
        店舗
  %li
    .menu_item
      - unless current_page?(shop_reviews_path(@shop))
        = link_to '口コミ', shop_reviews_path(@shop)
      - else
        口コミ
  %li
    .menu_item
      - unless current_page?(shop_photos_path(@shop))
        = link_to '写真', shop_photos_path(@shop)
      - else
        写真

request.path から判定する

helperを用意して、request.path に指定した文字列が含まれているか判別するようにしてみました
/shops/:shop_id/photos/:photo_id のようなURLについても判別できるようになりました

課題

  • なんかコレジャナイ感...
  • photooffcial-photoがあったら、判定方法を変えないといけない
  • request.path.include?(string.to_s) というのがいけてない気がする。あまりないかもしれないけれど、routes.rbを変えたらどうなるの?
  • routes.rbで、resourcesは何か決まっているので、そこで判断してはどうだろう?

ソース

%ul.menu
  %li
    .menu_item
      - unless current_page?(shop_path(@shop))
        = link_to '店舗', @shop
      - else
        店舗
  %li
    .menu_item
      - unless request_path_include?('reviews')
        = link_to '口コミ', shop_reviews_path(@shop)
      - else
        口コミ
  %li
    .menu_item
      - unless request_path_include?('photos')
        = link_to '写真', shop_photos_path(@shop)
      - else
        写真

helperを用意

app/helpers/application_helper.rb
module ApplicationHelper

  def request_path_include?(string)
    request.path.include?(string.to_s)
  end

end

link_to_if_with_block を使う

課題はあるままだけれど、テンプレートで同じことを書いているので1回で書けるようにしてみた

課題

  • 課題は残っている
  • url_for() を調べたらまだ何か別な方法がありそう

ソース

%ul.menu
  %li
    - shop_menu = current_page?(shop_path(@shop))
    .menu_item{style: shop_menu ? "color: red;" : ""}
      = link_to_if_with_block !shop_menu, @shop do
        店舗
  %li
    - reviews_menu = request_path_include?('reviews')
    .menu_item{style: reviews_menu ? "color: red;" : ""}
      = link_to_if_with_block !reviews_menu, shop_reviews_path(@shop) do
        口コミ
  %li
    - phtos_menu = request_path_include?('photos')
    .menu_item{style: phtos_menu ? "color: red;" : ""}
      = link_to_if_with_block !phtos_menu, shop_photos_path(@shop) do
        写真
app/helpers/application_helper.rb
module ApplicationHelper

  def request_path_include?(string)
    request.path.include?(string.to_s)
  end

  def link_to_if_with_block(condition, options = nil, html_options = nil, &block)
    if condition
      link_to(options, html_options, &block)
    else
      capture(&block)
    end
  end

end

まとめ?

contrller 名で判別してしまう方が、すっきりするかなあ?と思ったのですが、A/BテストなどでControllerを入れ替えてしまう、ということをすると適用できないと思います。

現在のURLから判別するのは、URLが変化しない、という前提があるからだけれど、かっこ悪さを感じるのは何故なんだろう?

どんな方法が他にあるか、聞いてみたい

13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12