1

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その設定を通じて、トピックまたはプロジェクトの完全なURLを取得しようとしています。

この小さなケースでは、ヘルパーメソッドを使用して条件を打ち出すことができると思いますが、ネストされたモデルのペアが数十ある場合に、これにどのようにアプローチするかを知りたいと思います。

4

2 に答える 2

0

あなたはサブスクリプションについて言及していますが、あなたのルートは完全に異なります。あなたが与えたルートはその時のほんの一例だったと思います。まず、作成したカスタムのparent_resourceメソッドを削除することから始めます。おそらく、belongs_toを追加することで、また必要に応じて条件を使用して、同じことをより簡単に行うことができます。

belongs_to :projects, :through => :topics, :conditions => ['whatever your conditions are']

親タイプごとに1つあるので、次のようなことができます。

object.project.present? 

そしてそこから、ネストされているかどうかを簡単に知ることができ、レールに親トラバーサルを実行させることで物事を単純化できます。それは、少なくともあなたが持っているサブスクリプションのタイプをかなり簡単に理解できるところまで、物事を十分に単純化するはずです。次に、一致するルートをいくつか追加するか、:as =>'somename'をルートに詰め込んで、ネストされた部分を特定した後で直接呼び出すことができるようにします。1つのオプションは次のようになります。

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
于 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 に答える