1. ホーム
  2. ruby-on-rails

[解決済み】Rails: respond_toブロックはどのように動作しますか?

2022-04-05 21:34:58

質問

を通過しています。 Rails入門 のガイドで、6.7節で混乱しました。scaffoldを生成した後、私のコントローラに以下の自動生成されたブロックが見つかりました。

def index
  @posts = Post.all

  respond_to do |format|
    format.html  # index.html.erb
    format.json  { render :json => @posts }
  end
end

respond_toブロックが実際にどのように動作するのか理解したい。formatはどのようなタイプの変数ですか?.htmlや.jsonはformatオブジェクトのメソッドなのでしょうか?また、その ドキュメント に対して

ActionController::MimeResponds::ClassMethods::respond_to

は質問に答えていない。

どのように解決するのですか?

私はRubyの初心者ですが、この同じコードで行き詰まりました。私がつまずいた部分は、ここで見つけたいくつかの答えよりももう少し基本的なものでした。これは誰かの役に立つかもしれないし、そうでないかもしれません。

  • respond_to はスーパークラスのメソッド ActionController .
  • はブロックを受け取ります。これはデリゲートのようなものです。このブロックは do まで end である。 |format| をブロックの引数として指定します。
  • respond_to はブロックを実行し、レスポンダを format 引数で指定します。

http://api.rubyonrails.org/v4.1/classes/ActionController/Responder.html

  • Responder に対するメソッドは含まれていません。 .html または .json しかし、私たちはこれらのメソッドをとにかく呼び出すのです この部分は私を混乱させました。
  • Rubyには method_missing . 存在しないメソッドを呼び出した場合 (たとえば json または html )、Ruby は method_missing メソッドに置き換えます。

http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

  • Responder クラスはその method_missing を一種の登録として使用します。json'を呼び出すと、拡張子が.jsonのリクエストに対して、jsonにシリアライズして応答するよう指示していることになります。そのためには html を引数なしで指定すると、デフォルトの方法 (規約とビューを使用) で .html リクエストを処理するようになります。

このように書くこともできます(JS的な擬似コードを使って)。

// get an instance to a responder from the base class
var format = get_responder()

// register html to render in the default way
// (by way of the views and conventions)
format.register('html')

// register json as well. the argument to .json is the second
// argument to method_missing ('json' is the first), which contains
// optional ways to configure the response. In this case, serialize as json.
format.register('json', renderOptions)

この部分は、私を混乱させました。今でも直感的でないと思っています。Rubyはこのテクニックをかなり使っているようです。クラス全体( responder ) がメソッドの実装になります。を活用するために method_missing そのため、メソッドに似たオブジェクトを渡すコールバックを渡さなければならない。20数年間C言語ライクな言語でコーディングしてきた人間にとって、これは非常に後ろ向きで直感的ではありません。それが悪いというわけではありません。しかし、そのような背景を持つ多くの人が頭を悩ませることであり、OPが求めていたことかもしれません。

p.s. RoR 4.2での注意点 respond_to に抽出されました。 レスポンダー gemを使用しています。