【问题标题】:How to find the parent model of a polymorphic nested resource in the index action?如何在索引操作中找到多态嵌套资源的父模型?
【发布时间】:2012-12-28 16:51:27
【问题描述】:

我想在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

在我的AddressesControllerindex动作中我想加载父模型,但是根据匹配的路由,包含父ID的参数name会发生变化:

/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)

最困扰我的是,每当我添加新的嵌套路由时,我都必须更新我的控制器。

有没有更好的方法来确定父模型? (除了简单地重构上面的代码)

【问题讨论】:

  • 我的方法与您上面的方法非常相似。我希望有人能给你一个好的答案,因为我也很想清理它。

标签: ruby-on-rails ruby-on-rails-3.2 url-routing


【解决方案1】:

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 = ...

【讨论】:

  • 我给出一个更广泛的答案,因为这是一个常见问题。获取父对象在其他操作中可能很有用。
猜你喜欢
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多