1

在 Rails 3.2 中工作,我是一个多态订阅模型,它的订阅类型可能是也可能不是嵌套资源。我正在尝试在电子邮件视图中显示完整的 URL 链接,但不知道该资源是否嵌套。

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

有没有办法识别嵌套资源的路由路径?如果我可以将模型与路线匹配,我可以填写必要的 ID。

截至目前,我已经在我的模型中定义了一个parent_resource :model可以遍历的方法,但我希望有更好的方法。

在我的routes.draw

  resources :projects do
    resources :topics do
      resources :comments
    end
  end

  resources :subscriptions

(我意识到我不应该嵌套那么深)

编辑:附加信息

我的订阅模型是我用来管理通知的资源。可订阅类型提供了一个链接,该链接可在该 subscribable_type / subscribable_id 上切换该用户的订阅打开或关闭。

然后,我通过一个Notifier < ActionMailer::Base提供订阅实例的服务,然后向用户发送邮件。

通过该设置,我试图获取subscription.subscribable可能是主题或项目的完整网址。

我意识到我可以通过辅助方法来确定这个小案例中的条件,但我很想知道如果有几十个嵌套模型对如何处理这个问题。

4

2 回答 2

0

您提到订阅,但您的路线完全不同。我猜你给出的路线只是一个例子。我将首先尝试摆脱您创建的自定义 parent_resource 方法。您可以通过添加 belongs_to 来做同样的事情,如果您也需要,也可以添加条件:

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

因此很明显,您可以通过以下方式指定您现在想要的网址:

if @object.project.present? 
  project_subscription_path(@object)
else
  other_subscription_path(@object)
end
于 2012-05-25T21:33:06.403 回答
0

这可能不是完成我正在做的事情的最佳方式,但这对我现在有用。

这会从最短的有效路由助手构建一个嵌套资源数组并生成一个 URL:

(测试于rails console

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" 
于 2012-05-25T23:48:40.750 回答