0

Rails 3.2.8. このルートがある場合:

  namespace :some_module do
    resources :some_models
  end

そして、対応する SomeModel はモジュールではなく、 SomeModule::SomeModelsController でモデル インスタンスとして場所を指定すると (作成のように)、URL に関する仮定が間違ってしまいます。

respond_with @some_model, location: @some_model

URL が some_module_some_model_instance_url ではなく some_model_instance_url であると想定するためです。

何らかの理由で、トリッキーになり、create メソッドで正しい URL と思われるものを一般的に評価しようとすると (これはコントローラーに含めるための一般的なモジュールにあるため):

respond_with @some_model, location: send("#{self.class.name.chomp('Controller').gsub('::','_').underscore.singularize}_url")

結果は次のようになります: No route matches {:action=>"show", :controller=>"some_module/some_models"}(これは複数なので、ルートはありません)

これはちょっと混乱しているようです。

しかし、やっているだけです:

respond_with @some_model

コントローラーが json で応答するように設定されている場合:

respond_to :json

私にとっては、作成されたインスタンスの ID を示さずに 204 を返します。クライアントがそれを利用するには、ID を含む何らかの指示が必要なようです (ID を返さずに何かを作成することはお勧めできません)。

モデルとは異なるモジュールにあるコントローラーの create メソッドで Respond_with を使用する正しい方法は何ですか?作成されたオブジェクトの ID の表示を返したいですか?

4

1 に答える 1

0

コントローラーで、コントローラーとモデルのどちらもモジュールではない場合、場所を指定するには、次を使用できます。

respond_with @some_model, location: @some_model

ただし、コントローラーは別のモジュールにあるため、コントローラーの create メソッドでこれを行うと、メソッド some_model_url(id) を評価しようとしますが、コントローラーで定義されているのは some_module_some_model_url(id) です。

したがって、それを行う方法の1つは次のようになります。

respond_with @some_model, location: some_module_some_model_url(@some_model.id)

コントローラーに含まれる汎用モジュールの場合、インスタンス メソッドは次のようになります。

def initialize
  super
  qualified_controller_name = self.class.name.chomp('Controller')
  @model_class = qualified_controller_name.split('::').last.singularize.constantize
  @model_singular_name_url_method_name_sym = "#{qualified_controller_name.gsub('::','_').underscore.singularize}_url".to_sym
  class_eval "def #{@model_singular_name}(id); #{@model_singular_name_url_method_name_sym}(id); end"
end

def create
  @value = @model_class.new(...)
  @value.save
  respond_with @value, location: send(@model_singular_name_url_method_name_sym, @value.id)
end

これにより、ロケーション応答ヘッダーの URL としてロケーションが返されるため、仕様テストでは、投稿の後にこれを行う可能性があります。

location = response.headers['Location']
# now check that location looks correct, etc.

ただし、同僚が指摘したように、次のように定義する場合、場所を指定する必要はありません。

def some_module_some_model_url(record)
  some_model_url(record)
end

したがって、これを一般的に追加するには:

class_eval "def #{@model_singular_name}_url(record); #{@model_singular_name_url_method_name_sym}(record); end"

そして、あなただけが必要です:

def create
  @value = @model_class.new(...)
  @value.save
  respond_with @value
end
于 2012-10-12T17:55:23.267 に答える