3

我有三个模型,即图像、数据文件和视频。我想从所有三个模型中获取用户的最新内容。

这样做非常糟糕的一个可能是:

  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)

如何仅在一个查询中执行此操作以使代码更好。

4

2 回答 2

1

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)

这只是一个概念证明,如果您愿意,您甚至可以使用单表继承,这取决于每个内容模型具有的属性,考虑到这些对象通常包含标题、正文、指向的链接,这可能是更好的选择内容,网址和类似的东西,几乎没有区别。

如果您使用 STI,您需要Content为每个内容模型(例如ImageVideo)定义一个具有公共属性的基本模型(在这种情况下)和几个其他模型。这些模型继承自 Content 模型。请记住contents在您的数据库中有一个表,其中包含一个type列(其中将包含具有内容类型的字符串,例如“视频”)和子模型的所有列(是的,如果您使用这种方法,所有数据都将进入一张桌子)。

更新:单表继承方法有几个优点,例如,您在一个查询中获取所有内容的数据,以前的解决方案适合排序,但您仍然需要获取视频和其他特定数据与其他查询:

# 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

当然这些只是想法,真正的实现取决于你的问题和要求。

于 2012-08-08T07:30:51.410 回答
0

那么你可以在用户模型中做这样的事情:

def resources
  (images + videos + data_files).sort_by(&:created_at).reverse
end

然后打电话

User.find(8).resources.paginate(:page => params[:page],:per_page=> per_page)
于 2012-08-07T06:08:45.337 回答