2

アクションでネストされたリソースの親モデルを特定したいと考えていindexます。

重要:私はindexアクションについてのみ尋ねています。他のすべてのRESTアクションでは、親モデルを見つけるのは簡単です。また、SOで数回回答されています)

私はこれらのルートを持っています:

resources people do
  resources addresses, only: [:index]
end
resources locations do
  resources addresses, only: [:index]
end
resources events do
  resources addresses, only: [:index]
end

myのindexアクションでAddressesController親モデルを読み込みたいのですが、マッチしたルートによって親IDを含むパラメータ名が変わります:

/people/1/addresses     ->  person_id
/locations/1/addresses  ->  location_id
/events/1/addresses     ->  event_id

今、私は自分のindexアクションにこの醜いコードを持っています:

if params[:person_id]
  parent_id = params[:person_id]
  parent_type = Person
elsif params[:location_id]
  parent_id = params[:location_id]
  parent_type = Location
else params[:event_id]
  parent_id = params[:event_id]
  parent_type = Event
end

@addresses = Address.where(
       addressable_type: parent_type, 
       addressable_id: parent_id)

最も気になるのは、新しいネストされたルートを追加するたびにコントローラーを更新する必要があることです。

親モデルを決定するより良い方法はありますか? (上記のコードを単純にリファクタリングする以外に)

4

1 に答える 1

3

1つのアプローチ:parent_type/parent_idを使用したケース

before_filter :polymorphic_resource

def polymorphic_resource
  request.path_parameters.each do |key, value|
    if key =~ /_id\z/
      resource_name = key.gsub(/_id\z/, "")
      @parent_type = resource_name.classify.constantize
      @parent_id = value
    end
  end
end

@addresses = Address.where(
       addressable_type: @parent_type, 
       addressable_id: @parent_id)

2 アプローチ: 推奨

before_filter :polymorphic_resource

def polymorphic_resource
  request.path_parameters.each do |key, value|
    if key =~ /_id\z/
      resource_name = key.gsub(/_id\z/, "")
      @resource = resource_name.classify.constantize.find(value)
    end
  end
end

@addresses = @resource.addresses

3 のアプローチ: デフォルトとして名前が付けられたインスタンス変数を設定します。特定のニーズのために...

before_filter :polymorphic_resource

def polymorphic_resource
  request.path_parameters.each do |key, value|
    if key =~ /_id\z/
      resource_name = key.gsub(/_id\z/, "")
      instance_variable_set("@#{resource_name}", resource_name.classify.constantize.find(value))
    end
  end
end

@addresses = ...
于 2012-12-28T17:12:44.543 に答える