在Rails 3.2中工作,我是一个多态订阅模型,其subscribable_type可能是也可能不是嵌套资源。我正在尝试在电子邮件视图中显示完整的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
的完整网址,这可能是主题或项目。
我意识到我可以通过辅助方法来解决这个小案例中的条件,但我很想知道如果有几十个嵌套模型对会如何处理这个问题。
答案 0 :(得分:0)
您提到订阅但您的路线完全不同。我猜你给的路线只是一个例子。我将首先尝试摆脱您创建的自定义parent_resource方法。你可以通过添加belongs_to来更简单地做同样的事情,如果你需要的话可能还有条件:
belongs_to :projects, :through => :topics, :conditions => ['whatever your conditions are']
我有一种每父类型,所以我可以这样做:
object.project.present?
从那里我可以很容易地知道它是否嵌套,并通过让rails进行父遍历来简化事情。这应该简化到足以让你至少可以轻松找出你的订阅类型的地方。接下来,我可能会添加一些匹配的路线或尝试填写:as =&gt; '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
答案 1 :(得分: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"