すべての苦痛なしで`Respond_to`
Railsでスキャフォールドを生成すると、通常のrespond_to
が表示されます。 ブロック:
def destroy
@task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
ただし、index
などの一部のアクション 、持っていない!
# GET /tasks
# GET /tasks.json
def index
@tasks = Task.all
end
これは悪いです。なんで? /tasks.txt
を押した場合 、およびtxt
アプリでサポートされていない場合、間違ったエラーが発生します:
ActionView::MissingTemplate (Missing template tasks/index, application/index with {:locale=>[:en], :formats=>[:text], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}
これは正しくありません。 適切なファイルが見つからないということではなく、サポートしていない形式を要求していることをクライアントに伝える必要があります。
これがUnknownFormat
の場合 エラーの場合は、より適切な応答コードを返すことができます。代わりに、これらのエラーは他の無関係なエラーと混ざり合い、処理が非常に困難になります。
respond_to
を追加できます index
にブロックする アクション:
# GET /tasks
# GET /tasks.json
def index
@tasks = Task.all
respond_to do |format|
format.html
format.json
end
end
次に、予想される例外とエラーコードを取得します。
Started GET "/tasks.txt" for 127.0.0.1 at 2014-11-03 22:05:12 -0800
Processing by TasksController#index as TEXT
Completed 406 Not Acceptable in 21ms
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/tasks_controller.rb:8:in `index'
ずっといい。 ただし、すべてのコントローラーにrespond_to
を散らかす クレイジーです。 レールっぽくない感じがします。 DRYに違反します。そして、それはあなたのコントローラーが実際に行っている仕事からあなたをそらします。
あなたはまだ悪いフォーマットを正しく扱いたいです。それで、あなたは何をしますか?
respond_to
ショートカット
オブジェクトをレンダリングするために特別なことを何もしていない場合は、ショートカットを使用できます。あなたが書く場合:
def index
@tasks = Task.all
respond_to :html, :json
end
完全なrespond_to
を作成するのと同じように機能します index
のブロック 。 これは、アクションが認識しているすべての形式についてRailsに伝えるための簡単な方法です。 また、さまざまなアクションがさまざまな形式をサポートしている場合、これは多くのコードなしでそれらの違いを処理するための良い方法です。
ただし、通常、コントローラーの各アクションは同じで機能します。 フォーマット。 index
の場合 json
に応答します 、new
、およびcreate
、およびその他すべて。 respond_to
があればいいのにと思います これはコントローラー全体に影響します:
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
respond_to :html, :json
# GET /tasks
# GET /tasks.json
def index
@tasks = Task.all
respond_with(@tasks)
end
そしてこれは実際に機能します:
Started GET "/tasks.txt" for 127.0.0.1 at 2014-11-03 22:17:37 -0800
Processing by TasksController#index as TEXT
Completed 406 Not Acceptable in 7ms
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/tasks_controller.rb:8:in `index'
まさに私たちが望んでいた種類のエラーです!そして、それを行うために各アクションを台無しにする必要はありませんでした。
モデルの状態に応じて、さまざまなことをしたい場合があります。 たとえば、create
の場合 、モデルが有効かどうかに応じて、フォームをリダイレクトまたは再レンダリングします。
Railsはこれを処理できます。ただし、respond_with
を使用して、チェックするオブジェクトを指定する必要があります。 。代わりに:
def create
@task = Task.new(task_params)
respond_to do |format|
if @task.save
format.html { redirect_to @task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: @task }
else
format.html { render :new }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
あなたが書くことができます:
def create
@task = Task.new(task_params)
flash[:notice] = "Task was successfully created." if @task.save
respond_with(@task)
end
このようにして、応答する形式からコードを分離します。 Railsに1回伝えることができます 処理するフォーマット。すべてのアクションでそれらを繰り返す必要はありません。
Rails 4.2には、キャッチがあります:respond_with
含まれなくなりました。 ただし、responders
をインストールすると、元に戻すことができます 宝石。 そしてresponders
gemには、他にもいくつかの優れた機能があります。
フラッシュメッセージはrespond_with
で設定できます responders :flash
を含めることによって コントローラの上部:
class TasksController < ApplicationController
responders :flash
便利なことに、ロケールファイルでこれらのフラッシュメッセージのデフォルトを設定できます。
また、responders
がいる場合 Gemfile
内のgem Railsスキャフォールドを生成すると、ジェネレーターはrespond_with
を使用してコントローラーを作成します respond_to
の代わりに :
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
respond_to :html, :json
def index
@tasks = Task.all
respond_with(@tasks)
end
def show
respond_with(@task)
end
# ...
これは、Railsに付属している足場よりもはるかにクリーンです。
最後に、特定のコントローラーアクションの形式でのみ応答する場合は、respond_to
を呼び出すことができます。 複数回:
class TasksController < ApplicationController
respond_to :html
respond_to :js, only: :create
end
最後のヒントのコメントでJeroenWeeinkに感謝します!
respond_with
またはrespond_to
?
さまざまな形式でさまざまな情報を返したい場合は、いくつかのオプションがあります。 コントローラーレベルのrespond_to
respond_with
と組み合わせる 短いコントローラーを取得するための優れた方法です。ただし、すべてのコントローラーアクションが同じ形式に応答し、Railsが期待する方法で動作する場合に最も役立つ傾向があります。
ただし、場合によっては、動作が異なるいくつかのアクションを実行できるようにしたいことがあります。ワンライナーrespond_to
そのような状況に対処するのに最適です。
さらに制御が必要な場合は、完全なrespond_to
を使用してください ブロックを使用すると、各フォーマットを好きなように処理できます。
これらのいずれかを使用すると、サポートされていない形式のリクエストで正しいエラーが発生します。また、アプリとそのクライアントの両方が混乱することはほとんどありません。
-
MongoDBコレクションのすべての名前を取得します
元々は2019年1月18日にObjectRocket.com/blogで公開されました。 スキーマを検証したり、フィールドのタイプミスをデバッグしたり、設定すべきでないフィールドを見つけたりするには、MongoDB®コレクションのすべてのキーを理解する必要があります。 ObjectRocketを含む多くのMongoDB-as-a-Service企業は、ユーザーインターフェイス(UI)でこれを行う簡単な方法を提供しています。経験豊富なMongoDBusersは通常、MongooseforJavaScript®やMongoengineforPython®などのオブジェクトドキュメントマッパ
-
MongoDBコレクション内のすべてのキーの名前を取得する
スキーマを検証したり、フィールドのタイプミスをデバッグしたり、設定されていないフィールドを見つけたりするには、MongoDBコレクションのすべてのキーを理解する必要があります。 多くのMongoDB-as-a-service企業は、ObjectRocketを含め、UIでこれを行う簡単な方法を提供しています。経験豊富なMongoDBユーザーは通常、JS用のMongooseやPython用のMongoengineなどのオブジェクトドキュメントマッパー(ODM)から始めます。これにより、アプリケーションの一貫したスキーマを構築し、タイプミスを減らすことができます。 (ODMは型の検証も行うため、整