正确的设计:一篇文章可以有一个用户(作者)加多个用户(标记用户)

发布于 2024-12-08 02:36:38 字数 359 浏览 0 评论 0原文

我遇到了一个有点卡住的情况。

一篇文章可以有一个用户(作为作者),一篇文章也可以有许多用户(因为一篇文章可以有其他用户在其中标记)。

在我的帖子模型中:

belongs_to :user
has_and_belongs_to_many :users

在我的用户模型中:

has_and_belongs_to_many :posts

一般情况下它工作得很好,但是当我想在我的帖子查询中包含用户并按作者姓名对帖子进行排序时,它会变得相当卡住。

正确的设计应该是怎样的?也许用author_id替换Post中的user_id?

I have a situation where I'm getting a bit stuck.

A Post can have a User (as an author), and a Post can also have many Users (as a post can have other users tagged in it).

In my Post model:

belongs_to :user
has_and_belongs_to_many :users

In my User model:

has_and_belongs_to_many :posts

It works fine generally, but is getting rather stuck when I want to include users on my posts query, and sort the posts by the author's name.

What should the correct design be? Perhaps replace user_id in Post with author_id?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风轻花落早 2024-12-15 02:36:38

我可以想象 UserUsers 搞乱了你的连接。但请注意,根据我的经验,这是 Rails 不能很好解决的问题。仅仅将其重命名为author(同时提高可读性/更好地表达意图)不会有帮助,因为它仍然指向同一个表users

当使用 Rails 进行多个连接时,很难正确表达您的条件。 Rails 动态地为您的表创建别名,不幸的是,我还没有找到在我的条件下解决这些别名的方法。

所以我认为你要么必须求助于手工编写的sql(这会很快),要么使用rails,首先根据作者姓名对帖子进行排序,然后检索每个帖子的标记用户列表(这会更慢) ,但纯红宝石)。

我会先选择第二个选项,然后根据需要优化到第一个选项。

[更新:添加作用域定义]

就我个人而言,我不赞成 default_scope ,而是建议定义一个显式作用域

scope :with_authors_sorted, lambda { 
  Post.includes(:type).includes(:user).
       order('year DESC, week DESC, users.display_name ASC, posts.created_at DESC') 
}

,然后您可以在控制器中使用它。

@posts = Post.with_authors_sorted

希望这有帮助。

I can imagine User and Users messing up your joins. But mind you, as far as my experience this is something that rails does not solve well. Just renaming it author (whilst improving the readability/expressing the intention better) will not help, since it will still point to the same table users.

When doing multiple joins with rails, it is very hard to express your conditions correctly. Rails creates aliases for your tables on the fly, unfortunately I have not find a way to address these aliases in my conditions.

So I think you will either have to resort to a handcrafted sql (which will be fast) or use rails, and get the posts sorted on author-name first, and then retrieve the list of tagged users per post second (which will be slower, but pure ruby).

I would go for the second option first, and optimize to the first if needed.

[UPDATE: add a scope definition]

Personally, I do not favor default_scope and instead would propose to define an explicit scope

scope :with_authors_sorted, lambda { 
  Post.includes(:type).includes(:user).
       order('year DESC, week DESC, users.display_name ASC, posts.created_at DESC') 
}

which you can then just use in your controller.

@posts = Post.with_authors_sorted

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文