我有三个模型,即图像,数据文件和视频。我想从这三个模型中获取用户的最新内容。
这样做的一个非常不好的可能是:
images = User.find(8).images
videos = User.find(8).videos
data_files = User.find(8).data_files
全部内容:
all_content = images + videos + data_files
all_content.sort_by(&:created_at).reverse.paginate(:page => params[:page],:per_page=> per_page)
如何在一个查询中做到这一点,以使代码更好。
最佳答案
拥有一个将用户连接到其内容的Content
模型可能是一个好主意。像这样:
class User < ActiveRecord::Base
has_many :contents
end
class Content < ActiveRecord::Base
belongs_to :user
# Remember the contentable_type and contentable_id columns
belongs_to :contentable, :polymorphic => true
end
# Similar relations for Image/File models
class Video < ActiveRecord::Base
has_one :content, :as => :contentable
belongs_to :user, :through => :content
end
# Then to fetch the last contents from the user
Content.where(:user_id => 8).order('created_at DESC')
.paginate(:page => params[:page], :per_page=> per_page)
这只是概念的证明,如果愿意,甚至可以使用single table inheritance,它取决于每个内容模型具有的属性,考虑到这些对象通常包含标题,正文和内容链接,可能会更好,网址和类似内容,并且几乎没有区别。
如果您使用STI,则需要定义一个具有通用属性的基本模型(在这种情况下为
Content
),并为每个内容模型(例如Image
或Video
)定义几个其他模型。这些模型从Content模型继承。请记住,在数据库中有一个contents
表,其中包含type
列(该列将包含具有内容类型的字符串,例如'Video')和子模型的所有列(是的,如果使用此方法,则所有数据将放在一张桌子上)。更新:单表继承方法具有多个优点,例如您可以在一个查询中获得所有内容的数据,以前的解决方案很适合排序,但是您仍然需要通过其他查询来获取视频和其他特定数据:
# The contents table has a type string column and
# all the specific models's columns
class Content < ActiveRecord::Base
end
# Video class inherit from Content (a Video is a Content!)
class Video < Content
end
在这种情况下,如果您想要所有用户的内容,则可以使用
user.contents
,并根据它们的类型获得特定对象(视频,图像等)的数组。您也可以只获取带有此类
Video.all
的图像或视频当然,这些只是想法,实际的实现取决于您的问题和要求。
关于ruby-on-rails - 订购来自三种不同型号的数据的 ruby ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11833666/