我有四个模型,允许由四个独立的注释控制器进行注释。这四个注释控制器的作用基本相同,只是略有不同。
为了消除四个基本相同的注释控制器的重复,我创建了一个Rails引擎作为gem,可以任意处理对我在routes.rb.中指定的任何任意模型的注释
因此,在我的routes.rb文件中,我现在可以使用:
comments_on :articles, :by => :users
comments_on在我的gem中实现如下:
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
路由显示在"rake routes"中,请求正确地被路由到我的gem的"CommentsController",但这就是我gem功能的终点。
在我的gem CommentsController中检测上下文的最佳方法是什么,这样我就可以处理特定于如何调用comments_on的请求?
更具体地说,在上下文感知的情况下,我将如何实现如下索引操作?
def index
@article = Article.find(params[:article_id])
@comments = ArticleComment.find(:all, :conditions => { :article_id => @article.id })
end
谢谢你的帮助!
您可以将主题指定为路由中的额外参数:
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
可以是所有这些模型都应该实现的命名作用域。
我过去也做过类似的模式,通常会有一个边缘案例打破这个想法,你最终会做更多的"元"编程。
我建议制作一个基本控制器,然后制作从中继承的简单控制器,或者尝试将这些常见行为拆分为模块。