久々の更新。しばらくRailsで趣味の開発に没頭しておりました。
というわけで 今回はRESTful Web APIs読書会(第三回)の参加報告を。
今回は主に「リソースの定義」と「HTTPリクエストの種類」と「安全性・べき等性」のお話。
・リソースの定義
リソースというと結構個人的に定義が曖昧で、データベースのデータとかがメインになるのかなと思っていたけど、どうやらRESTにおいて URIで表現されるものは全てリソースになるらしい。
そしてリソースの状態は以下の二つによって表現されうるらしい。
( 2013年12月1日改正、コメントより「リソースが(同じ状態で)複数の表現を持つ場合に、クライアントは望む表現をどのように指定するか、の選択肢である」といただきました。必ずしも二つではないということですね )
1. Content negotiation( 「内容ネゴシエーション」とも。HTTPリクエストとレスポンスから成るクライアントサーバ間のやり取り? )
2. URI( Railsで言うと new とか edit とかでURIが分かれてるイメージ? )
(続きを読む…)
基本的な部分はおさえたので そろそろ参考書から離れて 自分でつくってみようかなと思う。
そういうわけで現在は簡単なタスク管理のWebアプリケーションを実装中。
ユーザにストレスが無いよう利便性を高めるために以下のような仕様を実装したい。
【仕様】
1. 項目の既存の属性をクリックしたらテキストエリアに切り替わって編集モード。
2. テキストエリアからフォーカスを外すか、エンターキーを押した場合 更新 ( ただし文字数0の場合は更新せず元に戻す )
3. Escapeキーを押した場合は更新せず元に戻す
疑問に思った事や困った事、以下。
jQueryでupdate?
$.ajax を使う。jQueryの場合はデフォで「PUT」をサポートしてくれているので UPDATEも安心。
そんなわけで最初のajaxの中身は以下のような形になった。
(続きを読む…)
RESTful Web APIs 読書会 #2 に参加してきた。
RESTful Web API?
要約すると以下のような感じ。
・Webサービスだとハイパーリンクとかをたどって ユーザは目的達成できるけど、APIの場合って 多くの場合ドキュメントがWeb上に別個に公開されていて、URLだけ見てもわからない上に、ドキュメントを見ても個々の機能がどのように関連しているかがわかりにくいよね
・そもそも そういうWeb APIのあり方って 自己記述性の点でどうなの?(=RESTfulじゃないよね)
・自己記述的なものが含まれていて、最初のURLさえあれば使い方がわかるようなAPIが理想的だよね
そこで RESTful Web APIの著者は Collection+JSON というフォーマットを推奨している。
Collection+JSONとは?
JSONが汎用的でプレーンテキストを扱うものだとしたら、Collection+JSON とは JSONよりも限定的で 「Web上のリソースの検索可能なリストを公開するための規格」である。
HTTPヘッダでは Content-Type: application/vnd.collection+json という形で渡される。
(続きを読む…)
セッションまわりやら何やらいじっていたら大分いじれるようになってきた。最初こそ手こずったものの、基本的な機能であれば人に説明できるレベルになったかな…という所感。
正直学習ペース遅いよなーとは思いながらも、それでも自分が使う道具に関しては 人に教えられるくらいには仕組みや概念ごとの繋がりを理解しておきたいよね という思いもあるので。
というわけで、今回はRailsにおけるエラーページの独自実装ということで話を進めていく。
まずは controllers/application.rb に、以下の二つのクラスを定義。一つは404用、もう一つは403用。
class NotFound;end
class Forbidden;end
Applicationコントローラ内に以下のコードを追加。
rescue_from NotFound, with: :err_not_found
rescue_from Forbidden, with: :err_forbidden
:
:
def err_not_found(exception)
render "errors/not_found", status: 404
end
def err_forbidden(exception)
render "errors/forbidden", status: 403
end
これだけだとルーティングエラー等、根幹の部分で起きるエラーまでは拾ってくれない。
(続きを読む…)
引き続きRailsの勉強。
例えば前回までにつくった「article」モデルの「掲載期限」について、「掲載期限を指定しない」というチェックボックスを追加する場合を考える。チェックがされている場合は 掲載期限を保存しない。
この場合 テーブルの項目として新たにカラムを一つ追加するのも無駄があるので、アクセサメソッドを使用する。
まずはViewに変更を加える。 articles/_form.html.erb の掲載期限の部分に対し、noexpire というチェックボックスを実装。
<td>
<%= form.check_box :noexpire %> <%= form.label :noexpire %><br>
<%= form.date_select :expired_at, start_year: 1990, end_year: 2030, use_month_numbers: true %></td>
Articleモデルに以下のアクセサメソッドを追加。
def noexpire
expired_at.blank?
end
def noexpire(=val)
@noexpire = val.in?([1,"1",true])
end
フォーム項目と同名のアクセサメソッドを定義した。getterの方では フォームをページで読み込んだ際に返す値を記述し、setterの方では フォームをPOSTする際に @noexpire というインスタンス変数に対して「フォームから渡された値が 1,”1″,true のいずれかならtrue、そうでなければfalse」を代入。
ここでバリデーションが実行される前に行われる処理を記述する。
before_validation :fix_expired_at
:
(略)
:
def fix_expired_at
self.expired_at = nil if @noexpire
end
fix_expired_at では、POST時にsetterで定義された@noexpireの値がtrueなら(つまり「掲載期限を指定しない」にチェックされた状態なら)、データベースに格納する expired_at の値を「nil」にする、という処理が行われている。
因みに、何故ここに「self」をつける必要があるのか?以下のようにしてもいいんじゃないの?
def fix_expired_at
expired_at = nil if @noexpire
end
…と思ったけれど、上記がダメな理由は Ruby の根本原則を考えると自明で、上記のようにすると expired_at が 一関数内のローカル変数になってしまう という単純な理由だった。