Integrating polymorphic models into controllers views? how?

I'm having trouble trying to get this to work.

How the heck do you get a polymorphic controller to work? Especially integrating it with a view?

Let's say that we have shows, and episodes, then comments.

A show has many episodes, an episode has many comments.

the route is /shows/1/episodes/1/

Now to add a comment to that episode, how would I do it? Let's say that the comment is polymorphic, how do I create a dynamic view for polymorphic assocations? This has the same question towards a controller. I have taken a look at http://revolutiononrails.blogspot.com/2 ... llers.html but that still doesn't answer my question with two parents?

I need something like

- form_for([@parent1, @parent2, :comment]) do |f|   = f.text_area :comment   = f.submit 'Comment!'

Any help would be awesome, thanks!

Anyone?

Hi --

I'm having trouble trying to get this to work.

How the heck do you get a polymorphic controller to work? Especially integrating it with a view?

Let's say that we have shows, and episodes, then comments.

A show has many episodes, an episode has many comments.

the route is /shows/1/episodes/1/

Now to add a comment to that episode, how would I do it? Let's say that the comment is polymorphic, how do I create a dynamic view for polymorphic assocations? This has the same question towards a controller. I have taken a look athttp://revolutiononrails.blogspot.com/2 ... llers.html but that still doesn't answer my question with two parents?

I need something like

- form_for([@parent1, @parent2, :comment]) do |f|   = f.text_area :comment   = f.submit 'Comment!'

Any help would be awesome, thanks!

Try this in routes.rb:

   map.resources :shows do |s|      s.resources :episodes do |e|        e.resources :comments      end    end

and then in the view:

   <% form_for "comment", :url => comments_path(@show,@episode) do |f| %>

assuming you've set @show and @episode in the controller.

David

David,

Thanks, my question is how to make this:

<% form_for "comment", :url => comments_path(@show,@episode) do |f| %>

More dynamic, because it's a polymorphic model (comments)

Is there a way to make it so it can automatically pull the parents?

Something like <% form_for "comment", :url => comments_path(@parent1,@parent2) do |f| %>

And the controller will automatically figure out that @parent2 = episode and @parent1 = show.

Anyway to do that?

Hi --

David,

Thanks, my question is how to make this:

<% form_for "comment", :url => comments_path(@show,@episode) do |f| %>

More dynamic, because it's a polymorphic model (comments)

Is there a way to make it so it can automatically pull the parents?

Something like <% form_for "comment", :url => comments_path(@parent1,@parent2) do |f| %>

And the controller will automatically figure out that @parent2 = episode and @parent1 = show.

Anyway to do that?

OK, I see what you mean now. I wonder whether you could modify the railsrevolution code so that parent_resources took an array... and then you could do:

class CommentController < ApplicationController    parent_resources [:show, :episode], [:user, :post]

etc. I haven't tried it yet, but I think it could well work nicely.

(This is also reminding me that I really must get back to work on the Inferred Routes plugin, which lets you skip the parent nesting for nested resource routes, and see how it shapes up with all the recent changes.)

David

Whoops, I mean revolutiononrails. /me reaches for coffee....

David

Hi --

Hi --

David,

Thanks, my question is how to make this:

<% form_for "comment", :url => comments_path(@show,@episode) do |f| %>

More dynamic, because it's a polymorphic model (comments)

Is there a way to make it so it can automatically pull the parents?

Something like <% form_for "comment", :url => comments_path(@parent1,@parent2) do |f| %>

And the controller will automatically figure out that @parent2 = episode and @parent1 = show.

Anyway to do that?

OK, I see what you mean now. I wonder whether you could modify the railsrevolution code so that parent_resources took an array... and then you could do:

class CommentController < ApplicationController   parent_resources [:show, :episode], [:user, :post]

etc. I haven't tried it yet, but I think it could well work nicely.

Now I've tried it. Here's a first iteration, anyway. First, add these methods to the ones from the revolutiononrails blog post (in application.rb):

   def parent_ids(parent)      parent.map {|p| parent_id(p) }    end

   def parent_types      self.class.parents.detect {|parent| parent_ids(parent) }    end

   def parent_classes      parent_types && parent_types.map {|pt| parent_class(pt) }    end

   def parent_nest      parent_classes && parent_classes.zip(parent_types).map {|pc, pt|        pc.find_by_id(parent_id(pt))      }    end

Now, in comments_controller.rb:

   parent_resources [:show, :episode], [:user, :post]

   def new      @parent_nest = parent_nest      @comment = Comment.new # still one of my least favorite common                                # Rails idioms, but anyway    end

And then in the view -- this part could use some refinement:

   <% form_for @parent_nest << @comment do |f| %>

etc.

Since @parent_nest is already an array, you can't just list it alongside @comment inside an array -- though of course you could modify form_for so that that would be possible.

The kind of functional testing you'd want would be things like:

   def test_parent_nesting      CommentsController.parent_resources([:show, :episode], [:user, :post])      get("new", :user_id => 1, :post_id => 1)      assert_equal([:user, :post], @controller.send(:parent_types))      assert_equal([User, Post], @controller.send(:parent_classes))      assert_equal([User.find(1), Post.find(1)], @controller.send(:parent_nest))    end

Hopefully that will get you started.

David