3

画像、データファイル、ビデオの 3 つのモデルがあります。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)

コードを改善するために、これを 1 つのクエリで行うにはどうすればよいでしょうか。

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)

これは単なる概念実証です。必要に応じて、単一のテーブル継承を使用することもできます。これは、コンテンツ モデルのそれぞれが持つ属性に依存します。これらのオブジェクトには通常、タイトル、本文、リンクが含まれていることを考えると、おそらくより良い方法です。コンテンツ、URL、および同様のものといくつかの違い。

ContentSTI を使用する場合は、共通の属性を持つ基本モデル (この場合) と、コンテンツ モデルごとに他のいくつかのモデル (Imageまたは など)を定義する必要がありますVideo。これらのモデルは Content モデルから継承されます。contentsDB に 1 つのtype列 (「Video」などのコンテンツの種類を示す文字列を含む) と子モデルのすべての列 (はい、このアプローチを使用すると、すべてのデータが入ります)を持つテーブルを用意することを忘れないでください。単一のテーブル)。

UPDATE : 単一テーブル継承アプローチにはいくつかの長所があります。たとえば、1 つのクエリですべてのコンテンツのデータを取得できます。前のソリューションは並べ替えには適していますが、ビデオやその他の特定のデータを他のクエリで取得する必要があります。

# 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

User モデルで次のようなことができます。

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 に答える