【发布时间】:2011-03-11 15:49:26
【问题描述】:
我正在为以下目的设计一个认证模型。用户将拥有一组证书,例如 [A,B,C,D]。一篇文章也会有一组认证,比如 [B,D]。我希望能够找到他们的认证是用户认证的某个子集(阅读:任何子集)的文章。也就是说,如果文章有证书 [A,B,E] 它不会被退回,但如果它有 [A] 或 [A,D] 或任何它会正常返回。实际上,我设想的方式是将 user.certs 与 art.certs 相交并确保结果集等于 art.certs.size。我将其实现为 HABTM,因为我真的不需要访问连接对象,但在制定逻辑时遇到了麻烦。我最终做了这样的事情:
@certs = @user.certifications.collect{|c| c.id}
Article.all(:joins=>:certifications,
:group=>Article.attributes_for_sql,
:select=>'articles.*',
:conditions => ['certifications.id in (?)', @certs],
:having=> "count(articles.id)=(select (count(article_id)) from articles_certifications where article_id = articles.id group by article_id)")
这似乎可行,但非常难看。
无论如何,我应该如何设计这种关系以使其尽可能简单,示例解决方案应该是什么样的?
感谢您的帮助,我真的一直在用头撞墙。
【问题讨论】:
-
为什么选择HABTM?哪两个模型具有多对多关系?我只看到两个一对多的关系,你想在其中建立你的交集。
-
另外,您的第一行可能会重写为:@certs = @user.certifications.all(:select => "id") 这样,您只需从数据库,而不是整个对象。
-
证书是静态的。所以大约有 20 个。因此,有很多用户拥有金融认证,因此金融认证将拥有很多用户,因此调用 Certification.find_by_name('finance').users 将获得所有拥有它的用户。文章也是如此。如果您调用@article.certifications,您将获得所有证书,如果您调用@cert.articles,您将获得所有需要该证书的文章。编辑:我当然愿意接受其他建议。
-
好的,有道理。这部分有点令人困惑:“我希望能够找到他们的认证是用户文章的某个子集(阅读:任何子集)的文章。”用户也与文章相邻?
-
啊,我的错。那应该是证书。在原来的q中改变了它。感谢您找到它。
标签: sql ruby-on-rails ruby-on-rails-3 model