[rails] Problema polimorfismo


#1

Salve a tutti,

ho riscontrato un problema relativo alle associazioni polimorfiche,
magari qualcuno può darmi qualche dritta.

Ho un modello comments polimorfico, che può quindi essere associato a un
numero indefinito di altri modelli. Nel mio caso:

map.resources :articles do |articles|
articles.resources :comments
end

map.resources :posts do |posts|
posts.resources :comments
end

Sia articoli che posts possono essere commentati.

Le routes sono ok e funzionano come mi aspettavo, il problema é il mio
comments_controller.
In pratica se voglio creare un nuovo commento (per es. dall’url
/posts/2/comments/new) non ho modo nel metodo new di comments_controller
di capire se sto commentando un articolo o un post.

Qualcuno sa come risolvere?

Grazie


#2

Ciao,
cerco di mostrarti una possibile soluzione
Prima di tutto devi modificare le routes
così:

map.resources :posts do |post|
post.resources :comments, :controller => :post_comments
end

map.resources :articles do |article|
article.resources :comments, :controller => :article_comments
end

in questo modo mappi i commenti in due controller diversi in base alla
risorsa “padre”.
quindi devi definire due controllers che estendono il controller
CommentsController
così:
class ArticleCommentsController < CommentsController
protected
def load_parent
@parent = Article.find(params[:article_id])
end
end

class PostCommentsController < CommentsController
protected
def load_parent
@parent = Post.find(params[:post_id])
end
end

il metodo protected load_parent viene chiamato con before_filter nella
classe CommentsController, serve per caricare la risorsa padre del
commento.
Infine devi modificare il ComentsController

class CommentsController < ApplicationController
before_filter :load_parent

in questo modo il methodo load_parent viene chiamato prima di ogni
azione
poi puoi modificare il metodo create così (modificato dallo scaffold)

def create
@comment = @parent.comments.build(params[:comment])

respond_to do |format|
  if @comment.save
    flash[:notice] = 'Comment was successfully created.'
    format.html { redirect_to(url_for([@parent, @comment])) }
    format.xml  { render :xml => @comment, :status => :created,

:location => @comment }
else
format.html { render :action => “new” }
format.xml { render :xml => @comment.errors, :status =>
:unprocessable_entity }
end
end
end

e nella vista new.html.erb


<% form_for @comment, :url => url_for([@parent,Comment.new]) do |f| %>

ciao


#3

Grazie mille é un’ottima idea! Io al momento avevo risolto passando il
tipo di parent come argomento, ma così é più pulito nonostante si creino
tanti controllers quante risorse.