Ruby 分类话题,如何组织最有效?

kevinhua · 2012年03月28日 · 最后由 sqsy 回复于 2014年01月16日 · 2809 次阅读

分类话题,如何组织最有效?

以 Ruby China 源代码为基础,假设欲以 Topic 为基础,拓展开来:电影、书籍、游戏三类 Topic (除了:title 和:body 等共有属性外,还有一些特别属性,例如电影会有导演、主演、片长等属性)。以下有几种方案:

如果使用前两种方案,有没有可能使用:after_create 或:after_save 来设置"_type"值。

方法一:单表继承 (最简单)

class Movie < Topic
  ...
end

class MoviesController < TopicsController
  ...
end

方法二:共有属性单表继承,再 referenced 或 embeded 特别属性

class Movie < Topic
  has_one movie_profile
  ...
end

class MovieProfile
  belongs_to movie
  ...

end

class MoviesController < TopicsController
  ...
end

方法三:不使用类继承,把类别作为属性 (例如::category),共用一表

class Movie
  ...
  field :category, :type => :string
  ...
end

方法四:不使用类继承,把类别作为属性 (例如::category),共有属性一表,再 referenced 或 embeded 分别储存

class Movie
  ...
  field :category, :type => :string
  embeds movie_profile
  ...
end

class MovieProfile
  ...
  embeded_in movie
  ...
end

这四种方案,哪种方案最优?各有什么优缺点?

按这个需求,分为完全独立的 Model 最好

Similar Question and Solutions on StackOverFlow

####Question: Model inheritance and model specific code in the controller/view

I am using Rails single-table inheritance with a superclass Content and a number of subclasses (such as Article, Comment etc.) I am trying to get away with a single controller, and I have set up the routes thusly:

resources :contents
resources :articles, :controller => "contents"
resources :comments, :controller => "contents"
This way, /articles/new gets routed to contents#new which seems to be what I want.

Within the controller and the views, however, I need to tailor the functionality a bit depending on which actual model I am dealing with. For that purpose, I need to determine the original requested resource or otherwise find out which subclass I am dealing with.

Looking at params for /articles/newwithin the common controller gives {"action"=>"new", "controller"=>"contents"}, which obviously does not provide the information I need.

Either the answer is really obvious or I am using model inheritance wrong. Which one is it? :)

####Answer 1: You can extract the part of the request path you are interested in like this

path = request.fullpath[%r{^/(articles|comments)/}, 1] # articles or comments
Once you have it you can get the model class like that:

model_class = path.classify.constantize # Article or Comment Bests,

Richard

####Best Solution: Untilization of Routings

Brilliant, thanks. Further investigation showed that I can also do resources :comments, :controller => "contents", :type => "Comment" and then refer to params[:type]. But your solution also fits the bill and taught me classify and constantize. Thanks! – Sami Sep 3 '11 at 21:48

#1 楼 @Rei Thanks a lot! I found a solution from StackOverFlow.

承上:@topic = params[:type].camelize.constantize.new(params[:topic])

#4 楼 @kevinhua 通过字符串得到 “类名”,使用 String#classify比较好,因为会改为单数。比如

"events".camelize   # => "Events" 
"events".classify   # => "Event" 

#5 楼 @zhangyuan classify 只得到类名字符串,还需要转成常量:constantize

有时间再看一遍。Mark 一下。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号