Ruby on rails 查找嵌套或非嵌套资源的路径

Ruby on rails 查找嵌套或非嵌套资源的路径,ruby-on-rails,ruby-on-rails-3,activerecord,routes,Ruby On Rails,Ruby On Rails 3,Activerecord,Routes,在Rails3.2中,我使用了一个多态订阅模型,其subscribable_类型可能是也可能不是嵌套资源。我试图在电子邮件视图中显示完整的URL链接,但不知道该资源是否嵌套 当我在嵌套资源上尝试@model的url_时,它失败了,应该是[@parent,@model]的url_。不幸的是,我不知道如何发现Routes表中定义的父级 是否有方法标识嵌套资源的路由路径?如果我可以将模型与路线匹配,我可以填写必要的ID 到目前为止,我已经在我的模型中定义了一个名为parent_resource的方法:

在Rails3.2中,我使用了一个多态订阅模型,其subscribable_类型可能是也可能不是嵌套资源。我试图在电子邮件视图中显示完整的URL链接,但不知道该资源是否嵌套

当我在嵌套资源上尝试@model的url_时,它失败了,应该是[@parent,@model]的url_。不幸的是,我不知道如何发现Routes表中定义的父级

是否有方法标识嵌套资源的路由路径?如果我可以将模型与路线匹配,我可以填写必要的ID

到目前为止,我已经在我的模型中定义了一个名为parent_resource的方法:可以遍历的模型,但我希望有更好的方法

在我的路线内。绘制:

我意识到我不应该在这么深的地方筑巢

编辑:附加信息

我的订阅模型是用于管理通知的资源。Subscribable类型提供了一个链接,用于打开或关闭该用户在该Subscribable\u类型/Subscribable\u id上的订阅

然后,我通过订阅实例提供的通知程序 通过这个设置,我试图获取subscription.subscriptable的完整url,它可能是一个主题或项目


我意识到我可以通过一个helper方法敲出这个小案例中的条件,但我很好奇,如果有几十个嵌套模型对,人们会如何处理这个问题

您提到订阅,但您的路线完全不同。我猜你给出的路线只是一个例子。我将首先尝试摆脱您创建的自定义父资源方法。如果需要,您也可以通过添加“属于”来简化相同的操作,也可以通过添加条件来简化:

belongs_to :projects, :through => :topics, :conditions => ['whatever your conditions are']
我会为每种家长类型设置一个,这样我可以执行以下操作:

object.project.present? 
从那里我可以很容易地知道它是否嵌套,并通过让rails执行父遍历来简化事情。这应该可以使事情变得足够简单,至少你可以很容易地找到你的订阅类型。接下来,我可能会添加一些匹配的路由,或者尝试将:as=>“somename”填充到路由中,以便在确定嵌套部分后直接调用它们。一种选择是这样的:

match "projects/subscription/:id" => "projects#subscription", :as => :project_subscription
match "other/subscription/:id" => "other#subscription", :as => :other_subscription
因此,很明显,您可以通过以下方式指定您现在想要的url:

if @object.project.present? 
  project_subscription_path(@object)
else
  other_subscription_path(@object)
end

这可能不是完成我正在做的事情的最佳方式,但这对我现在来说很有效

这将根据最短有效路由帮助器构建嵌套资源数组,并生成URL:

在rails控制台中测试


您是否可以从您的路线文件中添加相关部分?谢谢。我已经进一步澄清了我的问题。我更想知道如何找到父级,而不是显式地命名父级的类名,即@object.project。我知道路由系统可以将多条路径路由到单个控制器,所以我明白为什么没有直接的方法可以做到这一点。但是,我仍然想知道是否有一种方法可以通过ActionDispatch::Route及其构建中的名称来识别路由?还是这让事情变得比需要的更复杂?
if @object.project.present? 
  project_subscription_path(@object)
else
  other_subscription_path(@object)
end
resource = Comment.first
resource_name = resource.class.to_s.downcase 

helper = Rails.application.routes.named_routes.helpers.grep(/.*#{resource_name}_path$/).first.to_s.split('_')
built = helper.slice!(-2,2) # Shortest possible valid helper, "comment_path"

while !(app.respond_to?(built.join("_").to_sym)) 
  built.unshift helper.pop
end

built.pop # Get rid of "path"
resources = built.reverse.reduce([]) { |memo, name| 
  if name == resource_name
    memo << resource
  else
    memo <<  memo.last.send(name.to_sym) # comment.topic, or topic.project (depends on belongs_to)
  end
}
resources.reverse!

app.polymorphic_url(resources) # "http://www.example.com/projects/1/topics/1/comments/1"