2011-06-06 50 views
0

我有四个模型,允许四个独立的注释控制器进行评论。这四个评论控制器的功能基本相同,只是略有不同。如何让宝石控制器处理多个任意模型?

为了消除基本上所有相同的四个注释控制器的重复,我创建了一个Rails引擎作为gem来任意处理对我在routes.rb中指定的任意模型的注释。

所以在我的routes.rb文件我现在可以使用:

comments_on :articles, :by => :users 

与comments_on实现为我的宝石如下:

def comments_on(*resources) 
    options = resources.extract_options! 

    [snip of some validation code] 

    topic_model = resources.first.to_s 
    user_model = options[:by].to_s 

    # Insert a nested route 
    Rails.application.routes.draw do 
    resources topic_model do 
     resources "comments" 
    end 
    end 
end 

的航线“耙路线”显示出来,并请求正确地路由到我的宝石的'CommentsController',但那是我的宝石功能结束的地方。

在我的gem CommentsController中检测上下文的最佳方式是什么,以便我可以处理特定于如何调用comments_on的请求?

更具体地说,我如何实现像下面这样的索引操作,让它能够识别上下文?

def index 
    @article = Article.find(params[:article_id]) 
    @comments = ArticleComment.find(:all, :conditions => { :article_id => @article.id }) 
end 

感谢您的帮助!

回答

1

您可以指定话题,因为在你的路由一个额外的参数:

Rails.application.routes.draw do 
    resources topic_model do 
    resources "comments", :topic_model => topic_model.to_s 
    end 
end 

那么你的控制器可以这样写:

def index 
    @topic = topic 
    @comments = topic.comments 
end 

protected 
def topic 
    m = params[:topic_model] 
    Kernel.const_get(m).find(params["#{m.underscore}_id"]) 
end 

你可以通过将大量逻辑的出控制器和模型。 topic.comments可能是所有这些模型应该实现的命名范围。

我在过去做过类似的模式,通常有一个边缘案例打破了这个想法,最终你做了更多的'元'编程,而不是明智的。

我建议制作一个基础控制器,然后再制作一个简单的控制器,或者尝试将这些常见行为分解为模块。