Rails 请教多个模型复用 Category 的办法

wuwx · March 10, 2013 · Last by vkill replied at March 14, 2013 · 3953 hits

是这样的,假设应用系统里有 电影(Movie),音乐(Music),图片(Image)这三个模型

而这三个模型都需要分类的支持 可能就会需要 MovieCategory,MusicCategory,ImageCategory 这三个分类模型

Movie belongs_to MovieCategory Music belongs_to MusicCategory Image belongs_to ImageCategory

但是 MovieCategory、MusicCategory、ImageCategory 这三个里面肯定有很多重复的代码。

所以希望系统可以只用一个 Category 模型代替 MovieCategory、MusicCategory、ImageCategory 这三个模型

这样就可以变成: Movie belongs_to Category Music belongs_to Category Image belongs_to Category

这样的话,应该如何设计 Category 的数据结构呢? 另外如果想取出 Movie 的所有分类应该如何编码可以显得比较美一些?

加个分类类型字段呢

#1 楼 @themorecolor 假如某个 category(比如“外语”, id=22)还想同时给 Movie 和 Music 用呢?

#2 楼 @wuwx 那用 多对多 关联?还得再多建三张表

#2 楼 @wuwx 好像 不对 有点晕 不过 要想只是 少写重复代码的话 给三个分类整个父类 重复代码放到里面 这样方便点吧

lz 怎么一说我也想起一个问题,我要查找所有分类是 English 的 Music 和 Movie 的话应该怎么写?顺路问一下..

感覺你需要的,如果不是 5 樓提到的 polymorphic association,大概就是 STI 了吧?http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Single+table+inheritance

#5 楼 @thisiskun 感觉不是用 polymorphic association 实现,因为并不是 category belongs_to movie

#7 楼 @mclee STI 好像也不是我需要的,因为不想建立 MusicCategory,MovieCategory,ImageCategory 三个子类 并且如果用 STI 的话,无法实现某个分类同时被用于 Music 和 Movie

思路: 1, Categorizable (Music, Movie) 与 Category 是多对多关系, 2, Category knows nothing about Categorizable, the connections between "Categorizable" and "Category" are made by a table named "Categorization"

偶觉得有时候打标签比用分类更方便,大不了一个标签代表一个分类,以后还可以扩展同时属于多个分类 gem acts as taggable on 如果自己做,也可以参见插件的源代码

#11 楼 @as181920 想把分类作为 tab 形式列出来:)

#12 楼 @wuwx 可以把标签也作为 tab 形式列出来,这个不影响。 如果考虑哪些分类/标签要列出来,是另外的事情了

#13 楼 @as181920 假如某分类下没有内容,同样需要列出来啊

#10 楼 @leomayleomay 那假如想列出 Movie 的所有分类应该如何写呢? 包括空的分类(就是还没有分类给某个 @movie 的分类----空分类)

@as181920 tag 跟 category 应该还是有区别的,一个是多对多,一个是一对多

@wuwx 感觉应该是用单表继承来做吧,Category 跟 Item 是一对多关系,Item 下有子类 Music,Book 等,子类共同属性放在 items 表,不同属性各自 has_one 实现,

Movie 所有分类可以这样 Category.joins(:items).where("items.type = ?", "Music")

#16 楼 @thisiskun 想列出 Movie 的所有的 Category 怎么办呢?包括没有被使用的 category

想偷懒就用 acts as taggable. category 可以看做单 tag

@wuwx, movie has_many :categories, :through => :categorizations

#18 楼 @everett #19 楼 @leomayleomay

这样显示不出来不被任何模型使用的 category 啊……

#20 楼 @wuwx 所以我说,要显示什么,可以考虑另外一个问题或者功能,就像 cms 一样,有个地方专门负责显示什么内容的逻辑。上面说的表关系,仅仅是关系。

@wuwx 你可以看一下 acts_as_taggable 的模型结构 他是 tag -> tagging <- tagger 的结构,我在上一个项目中就用借用了他的代码,再打了几个 patch,把 string basis 改成了 id basis, 其代码主要是在 core 模块中。你用 ActsAsTaggableOn::Tag.all 就能获得全部的 categories,然后就是 scope... 你也能自己通过搭多对多来做。道理和结构都是一样的。

category 封装起来用代理。

用 polymorphic http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

不过我也觉得用 tag 比较合适,不过这个 categories 可以作为节点

@Ddl1st 能解释一下这个做法吗?谢谢

#25 楼 @everett 以后使用更多的分类可以使代码可读性增强

26 Floor has deleted
27 Floor has deleted

就用 category 字段就好了,重复的代码写到 module

You need to Sign in before reply, if you don't have an account, please Sign up first.