うちのいぬ Tech Blog

Tech Blog of Uchinoinu/My dog

Rails4.x で 少数点(. ドット)を含めたURLを使いたい場合

やりたいこと

GET http://domain.jp/api/2.1.1/users

とか

GET http://domain.jp/meats/score/21293.02

とか、少数点、というかドットが入った形のURLを使う方法についてです。

(そもそもドットの入った値はURLに入れないほうが良いのかもしれませんが...)

失敗例

config/routes.rbに以下の様に指定。

get 'meats/score/:score' => 'meats#score'

routing_specを書きます。

it "routes to #score" do
  expect(:get => "/meats/score/5.4").to route_to("meats#score", score: "5.4", format: "json")
end

rspecを叩くと

No route matches "/meats/score/5.4"

この様に No route matches 扱いになります。

Railsはデフォルトではparameterにdotを受け付けない

こちらに記載されている通り、ドットをparameterに含めることは許容されていないようです。

By default the :id parameter doesn't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within an :id add a constraint which overrides this - for example id: /[^\/]+/ allows anything except a slash.

対応 - Constraintsで、paremeterを正規表現で指定する

Constraintsの意味(抜粋)

something that limits your freedom to do what you want [= restriction]

日本語にすると制約とか制限とか

なので、この場合には、 Parameterに対する制約 ということになります。

constraintsの使用例

resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }

↑だと /photos/AB1 とかになります

手っ取り早くパラメータにドット(小数点)を許容する方法

get 'meats/score/:score' => 'meats#score', score: /[^\/]

スラッシュ / 以外を許容します

形式を限定して小数点(ドット)許容する

数字+ドット+数字 の場合

get 'meats/score/5.1' => 'meats#score', constraints: { score: /\d+\.\d+/ }

2.2.2.2.2.2.2.2 の様な感じの場合

get 'meats/score/5.1' => 'meats#score', constraints: { score: /\d+(\.\d+)*/ }

api/v2.1.1/foo とかの場合

(そもそもURLを使ったapiのバージョニングがいいかどうかは置いておいて...)

↓の様なconstrainsを使うといいかと思います。

, constraints: { api_version:  /v\d+(\.\d+)*/ }

References

Back Button of NavBar Tapped when Incrementally Searching using SearchBarNavigationBar, search function cannot act correctly

Environment

Situation

  • Implement Incremental Search in TableViewController using SearchBar
  • Input search word
  • Leave by back button of nav bar, not x button or cancel button
  • Search cannot move correctly.

Initial View of Search

f:id:susanne:20160907143444p:plain

FirstResponder moves to search bar, and ....

f:id:susanne:20160907143456p:plain

date become vacant

incremental search

f:id:susanne:20160907143449p:plain

By inputting a character, result change.

But

Leave by back button of navigation item, not x button or cancel button, try to search again, and never go well. f:id:susanne:20160907143453p:plain

Cannot search correctly. Data does not change cancel button never been shown

solution

-set active of UISearchController false in viewWillDisappear

    var resultSearchController = UISearchController()

    override func viewWillDisappear(animated: Bool) {
        self.resultSearchController.active = false
    }

Solved well.

SearchBarでのインクリメンタルサーチ時にNavigationBarのBack Buttonで戻って再度検索をすると正常に動かない件

環境

状況

  • SearchBarを使ってTableViewControllerで、インクリメンタルサーチを実装
  • 検索ワードを入力
  • xボタンやcancelボタンではなく、戻るボタンで離脱
  • 再度検索をしようとしたら、正常に動かなかった

検索画面の初期状況

f:id:susanne:20160907143444p:plain

検索バーにFirstResponderが移ると

f:id:susanne:20160907143456p:plain

データが空になります

インクリメンタルサーチ

f:id:susanne:20160907143449p:plain

一文字入れる毎に結果が変わっていきます

しかしここで、

xボタンやキャンセルボタンではなく、NavigationItemのBack Buttonで離脱すると、再度検索しようとしたら以下の様になりました。 f:id:susanne:20160907143453p:plain

正常に検索ができず、検索の初期画面から変化しません。 cancelボタンも表示されません。

対応

  • viewWillDisappearにて、UISearchControllerをactive = false にします
    var resultSearchController = UISearchController()

    override func viewWillDisappear(animated: Bool) {
        self.resultSearchController.active = false
    }

これで正常に動くようになりました。

Calling and configuring UISearchController in viewWillAppear to implement Search View, SearchBar layout became bad

Environment

What's happened?

f:id:susanne:20160907120904g:plain

Collapsed layout of SearchBar

Search View

f:id:susanne:20160907105110p:plain

Input text in SearchBar

f:id:susanne:20160907105117p:plain

Search Result

f:id:susanne:20160907105134p:plain

Search Target Data can be divided to some layer, so use section and side index list to show them in TableView

Goes to detail page by tapping result cell and tapping back button of NavigationBar....

f:id:susanne:20160907105138p:plain

Width of SearchBar get small of size of width of side index list

And try to search again...

f:id:susanne:20160907105144p:plain

omg....

How to Overcome?

Problems

  • Called and Configured UISearchController in viewWillAppear
    • Search result data is not deleted when backed from detail page after searching. And Configure UISearchController in view will appear

Improve

  • Want to keep search result data and search word showed unless user intentionally delete them
    • So Call UISearchController in viewDidLoad

Result

f:id:susanne:20160907120918g:plain

Not so bad....

検索機能を実装する際に、UISearchControllerをviewWillAppearで呼んだら、ダメな感じになった

環境

何が起きたか

f:id:susanne:20160907120904g:plain

検索バーのレイアウトが崩れる

検索画面

f:id:susanne:20160907105110p:plain

検索バーにテキスト入力

f:id:susanne:20160907105117p:plain

検索結果

f:id:susanne:20160907105134p:plain

検索対象のデータが幾つかの階層に分けられるので、sectionで分けたり、サイドにsectionに応じたindexを表示させたりしています。

検索結果セルをタップして詳細画面にいって、NavigationBarのBackButtonで戻ると

f:id:susanne:20160907105138p:plain

サイドのindexの部分だけ検索バーが表示されなくなりました。

そのままサイド検索しようとすると

f:id:susanne:20160907105144p:plain

状況は変わりません。

どうしたら改善できたか

問題点

  • UISearchControllerの呼び出しや設定をviewWillAppearでやっていた
    • なので検索後の詳細ページから戻ったタイミングでtableViewからデータを削除したりさせていないので、UISearchControllerだけ再度設定されると、サイドのindexの部分だけ幅を取られてしまった

改善点

  • 検索結果や検索ワードは意図的に消さない限り保持していきたいので、UISearchControllerをviewDidLoadで先に呼んで設定しておく

結果

f:id:susanne:20160907120918g:plain

ある程度いい感じになりました