2

私はレールにかなり慣れていません。私は、次のような2つのモデル間の関係を作成するための最も効率的な方法を見つけようとしています。

  1. ユーザーは多くの曲を「お気に入りに追加」できます
  2. 曲には所有者がいます。

これが私が考えていることです。それは意味がありますか?

class User < ActiveRecord::Base
    has_many :songs #songs this user has favorited
end

class Song < ActiveRecord::Base
    belongs_to :user #the user whom submitted this song
end

この方法についての私の懸念は、特定のユーザーが所有している曲を特定するためだけに、データベース内のすべての曲に対してクエリを実行する効率がわからないことです。これについて私が考えるべき別の方法はありますか?

ちなみに、モデル名とは違う属性を呼べる方法はありますか?だから、モデルがまだ「歌」であるにもかかわらず、User.find(1).songs[0]私が言うことができるのではなく。User.find(1).favorites[0]

4

3 に答える 3

7

UserモデルとSongモデルの間には2つの別々の関係が必要です。つまり、「所有者」関係と「お気に入り」関係が必要になります。'owner'関係は、現在のように単純なhas_many/belongs_toにすることができます。「お気に入り」の関係は多対多であり、ここで説明するような関係をhabtm持つテーブルまたはファーストクラスモデルとして使用される結合テーブルが必要になります。has_many through

一般的に推奨されるアプローチは、has_many throughより適切に制御できるため、使用することです。

class User
  has_many :songs                                            # these are songs 'owned' by the user
  has_many :user_favorite_songs
  has_many :favorite_songs, :through => :user_favorite_songs # these are the favorites
end

class Song
  belongs_to :user
  has_many :user_favorite_songs
end

class UserFavoriteSong
  belongs_to :user
  belongs_to :favorite_song, :class_name => 'Song', :foreign_key => :song_id
end
于 2012-11-07T21:44:23.093 に答える
2

これは完全にうまく見えます。
Railsの関連付けは、最も効率的になるように努めています。時期尚早に最適化しないでください。

次のように、アソシエーションの名前にエイリアスを付けることができます。

class User < ActiveRecord::Base
  has_many :favorites, class_name: 'Song'
end

アソシエーションに関するドキュメントを参照してください。

とにかくパフォーマンスに関しては、:inverse_of関連付けオプションを確認することをお勧めします。

于 2012-11-07T21:47:56.077 に答える
1

私はこのコードをテストしていませんが、このようなものが必要になります。

class User < ActiveRecord::Base
  has_and_belongs_to_many :favorites, :class_name => "Song" #user's favorited songs
end

class Song < ActiveRecord::Base
  belongs_to :user #the user who submitted the song
  has_and_belongs_to_many :user, :as => :favorite
end

また、複数のユーザーが曲をお気に入りに追加できるため、「参加テーブル」が必要になります

CreateUsersFavorites < ActiveRecord::Migration
  def up
    create_table :users_favorites do |t|
      t.references :user
      t.references :favorite
    end
    create_index :users_favorites, :user_id
    create_index :users_favorites, :favorite_id
  end
  def down
    drop_table :users_favorites
  end
end

また、アクティブレコードの関係については、レールガイドを参照することを強くお勧めします。

于 2012-11-07T21:51:40.567 に答える